diff options
Diffstat (limited to 'net/ipv4/ipmr.c')
| -rw-r--r-- | net/ipv4/ipmr.c | 28 | 
1 files changed, 18 insertions, 10 deletions
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index 62212c772a4..65bcaa78904 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c @@ -157,9 +157,12 @@ static struct mr_table *ipmr_get_table(struct net *net, u32 id)  static int ipmr_fib_lookup(struct net *net, struct flowi4 *flp4,  			   struct mr_table **mrt)  { -	struct ipmr_result res; -	struct fib_lookup_arg arg = { .result = &res, };  	int err; +	struct ipmr_result res; +	struct fib_lookup_arg arg = { +		.result = &res, +		.flags = FIB_LOOKUP_NOREF, +	};  	err = fib_rules_lookup(net->ipv4.mr_rules_ops,  			       flowi4_to_flowi(flp4), 0, &arg); @@ -425,6 +428,7 @@ struct net_device *ipmr_new_tunnel(struct net *net, struct vifctl *v)  				goto failure;  			ipv4_devconf_setall(in_dev); +			neigh_parms_data_state_setall(in_dev->arp_parms);  			IPV4_DEVCONF(in_dev->cnf, RP_FILTER) = 0;  			if (dev_open(dev)) @@ -451,7 +455,7 @@ static netdev_tx_t reg_vif_xmit(struct sk_buff *skb, struct net_device *dev)  	struct mr_table *mrt;  	struct flowi4 fl4 = {  		.flowi4_oif	= dev->ifindex, -		.flowi4_iif	= skb->skb_iif, +		.flowi4_iif	= skb->skb_iif ? : LOOPBACK_IFINDEX,  		.flowi4_mark	= skb->mark,  	};  	int err; @@ -480,7 +484,7 @@ static void reg_vif_setup(struct net_device *dev)  	dev->type		= ARPHRD_PIMREG;  	dev->mtu		= ETH_DATA_LEN - sizeof(struct iphdr) - 8;  	dev->flags		= IFF_NOARP; -	dev->netdev_ops		= ®_vif_netdev_ops, +	dev->netdev_ops		= ®_vif_netdev_ops;  	dev->destructor		= free_netdev;  	dev->features		|= NETIF_F_NETNS_LOCAL;  } @@ -517,6 +521,7 @@ static struct net_device *ipmr_reg_vif(struct net *net, struct mr_table *mrt)  	}  	ipv4_devconf_setall(in_dev); +	neigh_parms_data_state_setall(in_dev->arp_parms);  	IPV4_DEVCONF(in_dev->cnf, RP_FILTER) = 0;  	rcu_read_unlock(); @@ -1658,7 +1663,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(skb, skb_dst(skb), NULL); +	ip_select_ident(skb, NULL);  	ip_send_check(iph);  	memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); @@ -2250,13 +2255,14 @@ int ipmr_get_route(struct net *net, struct sk_buff *skb,  }  static int ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb, -			    u32 portid, u32 seq, struct mfc_cache *c, int cmd) +			    u32 portid, u32 seq, struct mfc_cache *c, int cmd, +			    int flags)  {  	struct nlmsghdr *nlh;  	struct rtmsg *rtm;  	int err; -	nlh = nlmsg_put(skb, portid, seq, cmd, sizeof(*rtm), NLM_F_MULTI); +	nlh = nlmsg_put(skb, portid, seq, cmd, sizeof(*rtm), flags);  	if (nlh == NULL)  		return -EMSGSIZE; @@ -2324,7 +2330,7 @@ static void mroute_netlink_event(struct mr_table *mrt, struct mfc_cache *mfc,  	if (skb == NULL)  		goto errout; -	err = ipmr_fill_mroute(mrt, skb, 0, 0, mfc, cmd); +	err = ipmr_fill_mroute(mrt, skb, 0, 0, mfc, cmd, 0);  	if (err < 0)  		goto errout; @@ -2363,7 +2369,8 @@ static int ipmr_rtm_dumproute(struct sk_buff *skb, struct netlink_callback *cb)  				if (ipmr_fill_mroute(mrt, skb,  						     NETLINK_CB(cb->skb).portid,  						     cb->nlh->nlmsg_seq, -						     mfc, RTM_NEWROUTE) < 0) +						     mfc, RTM_NEWROUTE, +						     NLM_F_MULTI) < 0)  					goto done;  next_entry:  				e++; @@ -2377,7 +2384,8 @@ next_entry:  			if (ipmr_fill_mroute(mrt, skb,  					     NETLINK_CB(cb->skb).portid,  					     cb->nlh->nlmsg_seq, -					     mfc, RTM_NEWROUTE) < 0) { +					     mfc, RTM_NEWROUTE, +					     NLM_F_MULTI) < 0) {  				spin_unlock_bh(&mfc_unres_lock);  				goto done;  			}  | 
