diff options
Diffstat (limited to 'net')
28 files changed, 113 insertions, 97 deletions
| diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c index 4493913f0d5c..813db4e64602 100644 --- a/net/batman-adv/soft-interface.c +++ b/net/batman-adv/soft-interface.c @@ -168,6 +168,7 @@ static int batadv_interface_tx(struct sk_buff *skb,  	case ETH_P_8021Q:  		vhdr = (struct vlan_ethhdr *)skb->data;  		vid = ntohs(vhdr->h_vlan_TCI) & VLAN_VID_MASK; +		vid |= BATADV_VLAN_HAS_TAG;  		if (vhdr->h_vlan_encapsulated_proto != ethertype)  			break; @@ -331,6 +332,7 @@ void batadv_interface_rx(struct net_device *soft_iface,  	case ETH_P_8021Q:  		vhdr = (struct vlan_ethhdr *)skb->data;  		vid = ntohs(vhdr->h_vlan_TCI) & VLAN_VID_MASK; +		vid |= BATADV_VLAN_HAS_TAG;  		if (vhdr->h_vlan_encapsulated_proto != ethertype)  			break; diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c index b9259efa636e..e74ddc1c29a8 100644 --- a/net/bridge/br_netlink.c +++ b/net/bridge/br_netlink.c @@ -207,7 +207,7 @@ int br_getlink(struct sk_buff *skb, u32 pid, u32 seq,  	       struct net_device *dev, u32 filter_mask)  {  	int err = 0; -	struct net_bridge_port *port = br_port_get_rcu(dev); +	struct net_bridge_port *port = br_port_get_rtnl(dev);  	/* not a bridge port and  */  	if (!port && !(filter_mask & RTEXT_FILTER_BRVLAN)) @@ -451,7 +451,7 @@ static size_t br_get_link_af_size(const struct net_device *dev)  	struct net_port_vlans *pv;  	if (br_port_exists(dev)) -		pv = nbp_get_vlan_info(br_port_get_rcu(dev)); +		pv = nbp_get_vlan_info(br_port_get_rtnl(dev));  	else if (dev->priv_flags & IFF_EBRIDGE)  		pv = br_get_vlan_info((struct net_bridge *)netdev_priv(dev));  	else diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index 598cb0b333c6..efb57d911569 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h @@ -202,13 +202,10 @@ struct net_bridge_port  static inline struct net_bridge_port *br_port_get_rcu(const struct net_device *dev)  { -	struct net_bridge_port *port = -			rcu_dereference_rtnl(dev->rx_handler_data); - -	return br_port_exists(dev) ? port : NULL; +	return rcu_dereference(dev->rx_handler_data);  } -static inline struct net_bridge_port *br_port_get_rtnl(struct net_device *dev) +static inline struct net_bridge_port *br_port_get_rtnl(const struct net_device *dev)  {  	return br_port_exists(dev) ?  		rtnl_dereference(dev->rx_handler_data) : NULL; @@ -746,6 +743,7 @@ extern struct net_bridge_port *br_get_port(struct net_bridge *br,  extern void br_init_port(struct net_bridge_port *p);  extern void br_become_designated_port(struct net_bridge_port *p); +extern void __br_set_forward_delay(struct net_bridge *br, unsigned long t);  extern int br_set_forward_delay(struct net_bridge *br, unsigned long x);  extern int br_set_hello_time(struct net_bridge *br, unsigned long x);  extern int br_set_max_age(struct net_bridge *br, unsigned long x); diff --git a/net/bridge/br_stp.c b/net/bridge/br_stp.c index 1c0a50f13229..3c86f0538cbb 100644 --- a/net/bridge/br_stp.c +++ b/net/bridge/br_stp.c @@ -209,7 +209,7 @@ static void br_record_config_information(struct net_bridge_port *p,  	p->designated_age = jiffies - bpdu->message_age;  	mod_timer(&p->message_age_timer, jiffies -		  + (p->br->max_age - bpdu->message_age)); +		  + (bpdu->max_age - bpdu->message_age));  }  /* called under bridge lock */ @@ -544,18 +544,27 @@ int br_set_max_age(struct net_bridge *br, unsigned long val)  } +void __br_set_forward_delay(struct net_bridge *br, unsigned long t) +{ +	br->bridge_forward_delay = t; +	if (br_is_root_bridge(br)) +		br->forward_delay = br->bridge_forward_delay; +} +  int br_set_forward_delay(struct net_bridge *br, unsigned long val)  {  	unsigned long t = clock_t_to_jiffies(val); +	int err = -ERANGE; +	spin_lock_bh(&br->lock);  	if (br->stp_enabled != BR_NO_STP &&  	    (t < BR_MIN_FORWARD_DELAY || t > BR_MAX_FORWARD_DELAY)) -		return -ERANGE; +		goto unlock; -	spin_lock_bh(&br->lock); -	br->bridge_forward_delay = t; -	if (br_is_root_bridge(br)) -		br->forward_delay = br->bridge_forward_delay; +	__br_set_forward_delay(br, t); +	err = 0; + +unlock:  	spin_unlock_bh(&br->lock); -	return 0; +	return err;  } diff --git a/net/bridge/br_stp_if.c b/net/bridge/br_stp_if.c index d45e760141bb..108084a04671 100644 --- a/net/bridge/br_stp_if.c +++ b/net/bridge/br_stp_if.c @@ -129,6 +129,14 @@ static void br_stp_start(struct net_bridge *br)  	char *envp[] = { NULL };  	r = call_usermodehelper(BR_STP_PROG, argv, envp, UMH_WAIT_PROC); + +	spin_lock_bh(&br->lock); + +	if (br->bridge_forward_delay < BR_MIN_FORWARD_DELAY) +		__br_set_forward_delay(br, BR_MIN_FORWARD_DELAY); +	else if (br->bridge_forward_delay < BR_MAX_FORWARD_DELAY) +		__br_set_forward_delay(br, BR_MAX_FORWARD_DELAY); +  	if (r == 0) {  		br->stp_enabled = BR_USER_STP;  		br_debug(br, "userspace STP started\n"); @@ -137,10 +145,10 @@ static void br_stp_start(struct net_bridge *br)  		br_debug(br, "using kernel STP\n");  		/* To start timers on any ports left in blocking */ -		spin_lock_bh(&br->lock);  		br_port_state_selection(br); -		spin_unlock_bh(&br->lock);  	} + +	spin_unlock_bh(&br->lock);  }  static void br_stp_stop(struct net_bridge *br) diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c index 1606f740d6ae..2b4b32aaa893 100644 --- a/net/ceph/osd_client.c +++ b/net/ceph/osd_client.c @@ -2216,6 +2216,17 @@ void ceph_osdc_sync(struct ceph_osd_client *osdc)  EXPORT_SYMBOL(ceph_osdc_sync);  /* + * Call all pending notify callbacks - for use after a watch is + * unregistered, to make sure no more callbacks for it will be invoked + */ +extern void ceph_osdc_flush_notifies(struct ceph_osd_client *osdc) +{ +	flush_workqueue(osdc->notify_wq); +} +EXPORT_SYMBOL(ceph_osdc_flush_notifies); + + +/*   * init, shutdown   */  int ceph_osdc_init(struct ceph_osd_client *osdc, struct ceph_client *client) diff --git a/net/core/netpoll.c b/net/core/netpoll.c index 2c637e9a0b27..fc75c9e461b8 100644 --- a/net/core/netpoll.c +++ b/net/core/netpoll.c @@ -550,7 +550,7 @@ static void netpoll_neigh_reply(struct sk_buff *skb, struct netpoll_info *npinfo  		return;  	proto = ntohs(eth_hdr(skb)->h_proto); -	if (proto == ETH_P_IP) { +	if (proto == ETH_P_ARP) {  		struct arphdr *arp;  		unsigned char *arp_ptr;  		/* No arp on this interface */ @@ -1284,15 +1284,14 @@ EXPORT_SYMBOL_GPL(__netpoll_free_async);  void netpoll_cleanup(struct netpoll *np)  { -	if (!np->dev) -		return; -  	rtnl_lock(); +	if (!np->dev) +		goto out;  	__netpoll_cleanup(np); -	rtnl_unlock(); -  	dev_put(np->dev);  	np->dev = NULL; +out: +	rtnl_unlock();  }  EXPORT_SYMBOL(netpoll_cleanup); diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c index 9c61f9c02fdb..6cf9f7782ad4 100644 --- a/net/dccp/ipv6.c +++ b/net/dccp/ipv6.c @@ -135,6 +135,7 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,  		if (dst)  			dst->ops->redirect(dst, sk, skb); +		goto out;  	}  	if (type == ICMPV6_PKT_TOOBIG) { diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index d6c0e64ec97f..dace87f06e5f 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c @@ -369,7 +369,7 @@ static struct sk_buff *igmpv3_newpack(struct net_device *dev, int size)  	pip->saddr    = fl4.saddr;  	pip->protocol = IPPROTO_IGMP;  	pip->tot_len  = 0;	/* filled in later */ -	ip_select_ident(pip, &rt->dst, NULL); +	ip_select_ident(skb, &rt->dst, NULL);  	((u8 *)&pip[1])[0] = IPOPT_RA;  	((u8 *)&pip[1])[1] = 4;  	((u8 *)&pip[1])[2] = 0; @@ -714,7 +714,7 @@ static int igmp_send_report(struct in_device *in_dev, struct ip_mc_list *pmc,  	iph->daddr    = dst;  	iph->saddr    = fl4.saddr;  	iph->protocol = IPPROTO_IGMP; -	ip_select_ident(iph, &rt->dst, NULL); +	ip_select_ident(skb, &rt->dst, NULL);  	((u8 *)&iph[1])[0] = IPOPT_RA;  	((u8 *)&iph[1])[1] = 4;  	((u8 *)&iph[1])[2] = 0; diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c index 000e3d239d64..33d5537881ed 100644 --- a/net/ipv4/inetpeer.c +++ b/net/ipv4/inetpeer.c @@ -32,8 +32,8 @@   *  At the moment of writing this notes identifier of IP packets is generated   *  to be unpredictable using this code only for packets subjected   *  (actually or potentially) to defragmentation.  I.e. DF packets less than - *  PMTU in size uses a constant ID and do not use this code (see - *  ip_select_ident() in include/net/ip.h). + *  PMTU in size when local fragmentation is disabled use a constant ID and do + *  not use this code (see ip_select_ident() in include/net/ip.h).   *   *  Route cache entries hold references to our nodes.   *  New cache entries get references via lookup by destination IP address in diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 9ee17e3d11c3..a04d872c54f9 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -148,7 +148,7 @@ int ip_build_and_send_pkt(struct sk_buff *skb, struct sock *sk,  	iph->daddr    = (opt && opt->opt.srr ? opt->opt.faddr : daddr);  	iph->saddr    = saddr;  	iph->protocol = sk->sk_protocol; -	ip_select_ident(iph, &rt->dst, sk); +	ip_select_ident(skb, &rt->dst, sk);  	if (opt && opt->opt.optlen) {  		iph->ihl += opt->opt.optlen>>2; @@ -386,7 +386,7 @@ packet_routed:  		ip_options_build(skb, &inet_opt->opt, inet->inet_daddr, rt, 0);  	} -	ip_select_ident_more(iph, &rt->dst, sk, +	ip_select_ident_more(skb, &rt->dst, sk,  			     (skb_shinfo(skb)->gso_segs ?: 1) - 1);  	skb->priority = sk->sk_priority; @@ -1316,7 +1316,7 @@ struct sk_buff *__ip_make_skb(struct sock *sk,  	else  		ttl = ip_select_ttl(inet, &rt->dst); -	iph = (struct iphdr *)skb->data; +	iph = ip_hdr(skb);  	iph->version = 4;  	iph->ihl = 5;  	iph->tos = inet->tos; @@ -1324,7 +1324,7 @@ struct sk_buff *__ip_make_skb(struct sock *sk,  	iph->ttl = ttl;  	iph->protocol = sk->sk_protocol;  	ip_copy_addrs(iph, fl4); -	ip_select_ident(iph, &rt->dst, sk); +	ip_select_ident(skb, &rt->dst, sk);  	if (opt) {  		iph->ihl += opt->optlen>>2; diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index 9ae54b09254f..62212c772a4b 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c @@ -1658,7 +1658,7 @@ static void ip_encap(struct sk_buff *skb, __be32 saddr, __be32 daddr)  	iph->protocol	=	IPPROTO_IPIP;  	iph->ihl	=	5;  	iph->tot_len	=	htons(skb->len); -	ip_select_ident(iph, skb_dst(skb), NULL); +	ip_select_ident(skb, skb_dst(skb), NULL);  	ip_send_check(iph);  	memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index a86c7ae71881..bfec521c717f 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c @@ -387,7 +387,7 @@ static int raw_send_hdrinc(struct sock *sk, struct flowi4 *fl4,  		iph->check   = 0;  		iph->tot_len = htons(length);  		if (!iph->id) -			ip_select_ident(iph, &rt->dst, NULL); +			ip_select_ident(skb, &rt->dst, NULL);  		iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);  	} diff --git a/net/ipv4/tcp_metrics.c b/net/ipv4/tcp_metrics.c index 4a22f3e715df..52f3c6b971d2 100644 --- a/net/ipv4/tcp_metrics.c +++ b/net/ipv4/tcp_metrics.c @@ -502,7 +502,9 @@ reset:  	 * ACKs, wait for troubles.  	 */  	if (crtt > tp->srtt) { -		inet_csk(sk)->icsk_rto = crtt + max(crtt >> 2, tcp_rto_min(sk)); +		/* Set RTO like tcp_rtt_estimator(), but from cached RTT. */ +		crtt >>= 3; +		inet_csk(sk)->icsk_rto = crtt + max(2 * crtt, tcp_rto_min(sk));  	} else if (tp->srtt == 0) {  		/* RFC6298: 5.7 We've failed to get a valid RTT sample from  		 * 3WHS. This is most likely due to retransmission, diff --git a/net/ipv4/xfrm4_mode_tunnel.c b/net/ipv4/xfrm4_mode_tunnel.c index eb1dd4d643f2..b5663c37f089 100644 --- a/net/ipv4/xfrm4_mode_tunnel.c +++ b/net/ipv4/xfrm4_mode_tunnel.c @@ -117,7 +117,7 @@ static int xfrm4_mode_tunnel_output(struct xfrm_state *x, struct sk_buff *skb)  	top_iph->frag_off = (flags & XFRM_STATE_NOPMTUDISC) ?  		0 : (XFRM_MODE_SKB_CB(skb)->frag_off & htons(IP_DF)); -	ip_select_ident(top_iph, dst->child, NULL); +	ip_select_ident(skb, dst->child, NULL);  	top_iph->ttl = ip4_dst_hoplimit(dst->child); diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index 61355f7f4da5..2d8f4829575b 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c @@ -1656,9 +1656,9 @@ static int ip6_tnl_fill_info(struct sk_buff *skb, const struct net_device *dev)  	if (nla_put_u32(skb, IFLA_IPTUN_LINK, parm->link) ||  	    nla_put(skb, IFLA_IPTUN_LOCAL, sizeof(struct in6_addr), -		    &parm->raddr) || -	    nla_put(skb, IFLA_IPTUN_REMOTE, sizeof(struct in6_addr),  		    &parm->laddr) || +	    nla_put(skb, IFLA_IPTUN_REMOTE, sizeof(struct in6_addr), +		    &parm->raddr) ||  	    nla_put_u8(skb, IFLA_IPTUN_TTL, parm->hop_limit) ||  	    nla_put_u8(skb, IFLA_IPTUN_ENCAP_LIMIT, parm->encap_limit) ||  	    nla_put_be32(skb, IFLA_IPTUN_FLOWINFO, parm->flowinfo) || diff --git a/net/ipv6/netfilter/nf_nat_proto_icmpv6.c b/net/ipv6/netfilter/nf_nat_proto_icmpv6.c index 61aaf70f376e..2205e8eeeacf 100644 --- a/net/ipv6/netfilter/nf_nat_proto_icmpv6.c +++ b/net/ipv6/netfilter/nf_nat_proto_icmpv6.c @@ -69,8 +69,8 @@ icmpv6_manip_pkt(struct sk_buff *skb,  	hdr = (struct icmp6hdr *)(skb->data + hdroff);  	l3proto->csum_update(skb, iphdroff, &hdr->icmp6_cksum,  			     tuple, maniptype); -	if (hdr->icmp6_code == ICMPV6_ECHO_REQUEST || -	    hdr->icmp6_code == ICMPV6_ECHO_REPLY) { +	if (hdr->icmp6_type == ICMPV6_ECHO_REQUEST || +	    hdr->icmp6_type == ICMPV6_ECHO_REPLY) {  		inet_proto_csum_replace2(&hdr->icmp6_cksum, skb,  					 hdr->icmp6_identifier,  					 tuple->src.u.icmp.id, 0); diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c index f77139007983..f2e30fb31e78 100644 --- a/net/netfilter/ipset/ip_set_core.c +++ b/net/netfilter/ipset/ip_set_core.c @@ -1052,7 +1052,7 @@ ip_set_swap(struct sock *ctnl, struct sk_buff *skb,  	 * Not an artificial restriction anymore, as we must prevent  	 * possible loops created by swapping in setlist type of sets. */  	if (!(from->type->features == to->type->features && -	      from->type->family == to->type->family)) +	      from->family == to->family))  		return -IPSET_ERR_TYPE_MISMATCH;  	strncpy(from_name, from->name, IPSET_MAXNAMELEN); @@ -1489,8 +1489,7 @@ ip_set_utest(struct sock *ctnl, struct sk_buff *skb,  	if (ret == -EAGAIN)  		ret = 1; -	return (ret < 0 && ret != -ENOTEMPTY) ? ret : -		ret > 0 ? 0 : -IPSET_ERR_EXIST; +	return ret > 0 ? 0 : -IPSET_ERR_EXIST;  }  /* Get headed data of a set */ diff --git a/net/netfilter/ipset/ip_set_getport.c b/net/netfilter/ipset/ip_set_getport.c index 6fdf88ae2353..dac156f819ac 100644 --- a/net/netfilter/ipset/ip_set_getport.c +++ b/net/netfilter/ipset/ip_set_getport.c @@ -116,12 +116,12 @@ ip_set_get_ip6_port(const struct sk_buff *skb, bool src,  {  	int protoff;  	u8 nexthdr; -	__be16 frag_off; +	__be16 frag_off = 0;  	nexthdr = ipv6_hdr(skb)->nexthdr;  	protoff = ipv6_skip_exthdr(skb, sizeof(struct ipv6hdr), &nexthdr,  				   &frag_off); -	if (protoff < 0) +	if (protoff < 0 || (frag_off & htons(~0x7)) != 0)  		return false;  	return get_port(skb, nexthdr, protoff, src, port, proto); diff --git a/net/netfilter/ipset/ip_set_hash_gen.h b/net/netfilter/ipset/ip_set_hash_gen.h index 57beb1762b2d..707bc520d629 100644 --- a/net/netfilter/ipset/ip_set_hash_gen.h +++ b/net/netfilter/ipset/ip_set_hash_gen.h @@ -325,18 +325,22 @@ mtype_add_cidr(struct htype *h, u8 cidr, u8 nets_length)  static void  mtype_del_cidr(struct htype *h, u8 cidr, u8 nets_length)  { -	u8 i, j; - -	for (i = 0; i < nets_length - 1 && h->nets[i].cidr != cidr; i++) -		; -	h->nets[i].nets--; - -	if (h->nets[i].nets != 0) -		return; - -	for (j = i; j < nets_length - 1 && h->nets[j].nets; j++) { -		h->nets[j].cidr = h->nets[j + 1].cidr; -		h->nets[j].nets = h->nets[j + 1].nets; +	u8 i, j, net_end = nets_length - 1; + +	for (i = 0; i < nets_length; i++) { +	        if (h->nets[i].cidr != cidr) +	                continue; +                if (h->nets[i].nets > 1 || i == net_end || +                    h->nets[i + 1].nets == 0) { +                        h->nets[i].nets--; +                        return; +                } +                for (j = i; j < net_end && h->nets[j].nets; j++) { +		        h->nets[j].cidr = h->nets[j + 1].cidr; +		        h->nets[j].nets = h->nets[j + 1].nets; +                } +                h->nets[j].nets = 0; +                return;  	}  }  #endif diff --git a/net/netfilter/ipset/ip_set_hash_ipportnet.c b/net/netfilter/ipset/ip_set_hash_ipportnet.c index c6a525373be4..f15f3e28b9c3 100644 --- a/net/netfilter/ipset/ip_set_hash_ipportnet.c +++ b/net/netfilter/ipset/ip_set_hash_ipportnet.c @@ -260,7 +260,7 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[],  		e.ip = htonl(ip);  		e.ip2 = htonl(ip2_from & ip_set_hostmask(e.cidr + 1));  		ret = adtfn(set, &e, &ext, &ext, flags); -		return ip_set_enomatch(ret, flags, adt) ? 1 : +		return ip_set_enomatch(ret, flags, adt, set) ? -ret :  		       ip_set_eexist(ret, flags) ? 0 : ret;  	} @@ -544,7 +544,7 @@ hash_ipportnet6_uadt(struct ip_set *set, struct nlattr *tb[],  	if (adt == IPSET_TEST || !with_ports || !tb[IPSET_ATTR_PORT_TO]) {  		ret = adtfn(set, &e, &ext, &ext, flags); -		return ip_set_enomatch(ret, flags, adt) ? 1 : +		return ip_set_enomatch(ret, flags, adt, set) ? -ret :  		       ip_set_eexist(ret, flags) ? 0 : ret;  	} diff --git a/net/netfilter/ipset/ip_set_hash_net.c b/net/netfilter/ipset/ip_set_hash_net.c index da740ceb56ae..223e9f546d0f 100644 --- a/net/netfilter/ipset/ip_set_hash_net.c +++ b/net/netfilter/ipset/ip_set_hash_net.c @@ -199,7 +199,7 @@ hash_net4_uadt(struct ip_set *set, struct nlattr *tb[],  	if (adt == IPSET_TEST || !tb[IPSET_ATTR_IP_TO]) {  		e.ip = htonl(ip & ip_set_hostmask(e.cidr));  		ret = adtfn(set, &e, &ext, &ext, flags); -		return ip_set_enomatch(ret, flags, adt) ? 1 : +		return ip_set_enomatch(ret, flags, adt, set) ? -ret:  		       ip_set_eexist(ret, flags) ? 0 : ret;  	} @@ -396,7 +396,7 @@ hash_net6_uadt(struct ip_set *set, struct nlattr *tb[],  	ret = adtfn(set, &e, &ext, &ext, flags); -	return ip_set_enomatch(ret, flags, adt) ? 1 : +	return ip_set_enomatch(ret, flags, adt, set) ? -ret :  	       ip_set_eexist(ret, flags) ? 0 : ret;  } diff --git a/net/netfilter/ipset/ip_set_hash_netiface.c b/net/netfilter/ipset/ip_set_hash_netiface.c index 84ae6f6ce624..7d798d5d5cd3 100644 --- a/net/netfilter/ipset/ip_set_hash_netiface.c +++ b/net/netfilter/ipset/ip_set_hash_netiface.c @@ -368,7 +368,7 @@ hash_netiface4_uadt(struct ip_set *set, struct nlattr *tb[],  	if (adt == IPSET_TEST || !tb[IPSET_ATTR_IP_TO]) {  		e.ip = htonl(ip & ip_set_hostmask(e.cidr));  		ret = adtfn(set, &e, &ext, &ext, flags); -		return ip_set_enomatch(ret, flags, adt) ? 1 : +		return ip_set_enomatch(ret, flags, adt, set) ? -ret :  		       ip_set_eexist(ret, flags) ? 0 : ret;  	} @@ -634,7 +634,7 @@ hash_netiface6_uadt(struct ip_set *set, struct nlattr *tb[],  	ret = adtfn(set, &e, &ext, &ext, flags); -	return ip_set_enomatch(ret, flags, adt) ? 1 : +	return ip_set_enomatch(ret, flags, adt, set) ? -ret :  	       ip_set_eexist(ret, flags) ? 0 : ret;  } diff --git a/net/netfilter/ipset/ip_set_hash_netport.c b/net/netfilter/ipset/ip_set_hash_netport.c index 9a0869853be5..09d6690bee6f 100644 --- a/net/netfilter/ipset/ip_set_hash_netport.c +++ b/net/netfilter/ipset/ip_set_hash_netport.c @@ -244,7 +244,7 @@ hash_netport4_uadt(struct ip_set *set, struct nlattr *tb[],  	if (adt == IPSET_TEST || !(with_ports || tb[IPSET_ATTR_IP_TO])) {  		e.ip = htonl(ip & ip_set_hostmask(e.cidr + 1));  		ret = adtfn(set, &e, &ext, &ext, flags); -		return ip_set_enomatch(ret, flags, adt) ? 1 : +		return ip_set_enomatch(ret, flags, adt, set) ? -ret :  		       ip_set_eexist(ret, flags) ? 0 : ret;  	} @@ -489,7 +489,7 @@ hash_netport6_uadt(struct ip_set *set, struct nlattr *tb[],  	if (adt == IPSET_TEST || !with_ports || !tb[IPSET_ATTR_PORT_TO]) {  		ret = adtfn(set, &e, &ext, &ext, flags); -		return ip_set_enomatch(ret, flags, adt) ? 1 : +		return ip_set_enomatch(ret, flags, adt, set) ? -ret :  		       ip_set_eexist(ret, flags) ? 0 : ret;  	} diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c index b75ff6429a04..c47444e4cf8c 100644 --- a/net/netfilter/ipvs/ip_vs_xmit.c +++ b/net/netfilter/ipvs/ip_vs_xmit.c @@ -883,7 +883,7 @@ ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,  	iph->daddr		=	cp->daddr.ip;  	iph->saddr		=	saddr;  	iph->ttl		=	old_iph->ttl; -	ip_select_ident(iph, &rt->dst, NULL); +	ip_select_ident(skb, &rt->dst, NULL);  	/* Another hack: avoid icmp_send in ip_fragment */  	skb->local_df = 1; diff --git a/net/netfilter/nfnetlink_queue_core.c b/net/netfilter/nfnetlink_queue_core.c index 95a98c8c1da6..ae2e5c11d01a 100644 --- a/net/netfilter/nfnetlink_queue_core.c +++ b/net/netfilter/nfnetlink_queue_core.c @@ -1009,7 +1009,7 @@ nfqnl_recv_verdict(struct sock *ctnl, struct sk_buff *skb,  			verdict = NF_DROP;  		if (ct) -			nfqnl_ct_seq_adjust(skb, ct, ctinfo, diff); +			nfqnl_ct_seq_adjust(entry->skb, ct, ctinfo, diff);  	}  	if (nfqa[NFQA_MARK]) diff --git a/net/sctp/input.c b/net/sctp/input.c index 5f2068679f83..98b69bbecdd9 100644 --- a/net/sctp/input.c +++ b/net/sctp/input.c @@ -634,8 +634,7 @@ void sctp_v4_err(struct sk_buff *skb, __u32 info)  		break;  	case ICMP_REDIRECT:  		sctp_icmp_redirect(sk, transport, skb); -		err = 0; -		break; +		/* Fall through to out_unlock. */  	default:  		goto out_unlock;  	} diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c index da613ceae28c..e7b2d4fe2b6a 100644 --- a/net/sctp/ipv6.c +++ b/net/sctp/ipv6.c @@ -183,7 +183,7 @@ static void sctp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,  		break;  	case NDISC_REDIRECT:  		sctp_icmp_redirect(sk, transport, skb); -		break; +		goto out_unlock;  	default:  		break;  	} @@ -204,44 +204,23 @@ out:  		in6_dev_put(idev);  } -/* Based on tcp_v6_xmit() in tcp_ipv6.c. */  static int sctp_v6_xmit(struct sk_buff *skb, struct sctp_transport *transport)  {  	struct sock *sk = skb->sk;  	struct ipv6_pinfo *np = inet6_sk(sk); -	struct flowi6 fl6; - -	memset(&fl6, 0, sizeof(fl6)); - -	fl6.flowi6_proto = sk->sk_protocol; - -	/* Fill in the dest address from the route entry passed with the skb -	 * and the source address from the transport. -	 */ -	fl6.daddr = transport->ipaddr.v6.sin6_addr; -	fl6.saddr = transport->saddr.v6.sin6_addr; - -	fl6.flowlabel = np->flow_label; -	IP6_ECN_flow_xmit(sk, fl6.flowlabel); -	if (ipv6_addr_type(&fl6.saddr) & IPV6_ADDR_LINKLOCAL) -		fl6.flowi6_oif = transport->saddr.v6.sin6_scope_id; -	else -		fl6.flowi6_oif = sk->sk_bound_dev_if; - -	if (np->opt && np->opt->srcrt) { -		struct rt0_hdr *rt0 = (struct rt0_hdr *) np->opt->srcrt; -		fl6.daddr = *rt0->addr; -	} +	struct flowi6 *fl6 = &transport->fl.u.ip6;  	pr_debug("%s: skb:%p, len:%d, src:%pI6 dst:%pI6\n", __func__, skb, -		 skb->len, &fl6.saddr, &fl6.daddr); +		 skb->len, &fl6->saddr, &fl6->daddr); -	SCTP_INC_STATS(sock_net(sk), SCTP_MIB_OUTSCTPPACKS); +	IP6_ECN_flow_xmit(sk, fl6->flowlabel);  	if (!(transport->param_flags & SPP_PMTUD_ENABLE))  		skb->local_df = 1; -	return ip6_xmit(sk, skb, &fl6, np->opt, np->tclass); +	SCTP_INC_STATS(sock_net(sk), SCTP_MIB_OUTSCTPPACKS); + +	return ip6_xmit(sk, skb, fl6, np->opt, np->tclass);  }  /* Returns the dst cache entry for the given source and destination ip @@ -254,10 +233,12 @@ static void sctp_v6_get_dst(struct sctp_transport *t, union sctp_addr *saddr,  	struct dst_entry *dst = NULL;  	struct flowi6 *fl6 = &fl->u.ip6;  	struct sctp_bind_addr *bp; +	struct ipv6_pinfo *np = inet6_sk(sk);  	struct sctp_sockaddr_entry *laddr;  	union sctp_addr *baddr = NULL;  	union sctp_addr *daddr = &t->ipaddr;  	union sctp_addr dst_saddr; +	struct in6_addr *final_p, final;  	__u8 matchlen = 0;  	__u8 bmatchlen;  	sctp_scope_t scope; @@ -281,7 +262,8 @@ static void sctp_v6_get_dst(struct sctp_transport *t, union sctp_addr *saddr,  		pr_debug("src=%pI6 - ", &fl6->saddr);  	} -	dst = ip6_dst_lookup_flow(sk, fl6, NULL, false); +	final_p = fl6_update_dst(fl6, np->opt, &final); +	dst = ip6_dst_lookup_flow(sk, fl6, final_p, false);  	if (!asoc || saddr)  		goto out; @@ -333,10 +315,12 @@ static void sctp_v6_get_dst(struct sctp_transport *t, union sctp_addr *saddr,  		}  	}  	rcu_read_unlock(); +  	if (baddr) {  		fl6->saddr = baddr->v6.sin6_addr;  		fl6->fl6_sport = baddr->v6.sin6_port; -		dst = ip6_dst_lookup_flow(sk, fl6, NULL, false); +		final_p = fl6_update_dst(fl6, np->opt, &final); +		dst = ip6_dst_lookup_flow(sk, fl6, final_p, false);  	}  out: | 
