Commit 36b609df authored by David S. Miller's avatar David S. Miller

Merge bk://kernel.bkbits.net/jmorris/net-2.5

into nuts.ninka.net:/home/davem/src/BK/net-2.5
parents 3cee4c3f 9e9d4917
...@@ -217,7 +217,6 @@ struct pimreghdr ...@@ -217,7 +217,6 @@ struct pimreghdr
__u32 flags; __u32 flags;
}; };
extern int pim_rcv(struct sk_buff *);
extern int pim_rcv_v1(struct sk_buff *); extern int pim_rcv_v1(struct sk_buff *);
struct rtmsg; struct rtmsg;
......
...@@ -757,9 +757,10 @@ static void igmp_heard_report(struct in_device *in_dev, u32 group) ...@@ -757,9 +757,10 @@ static void igmp_heard_report(struct in_device *in_dev, u32 group)
read_unlock(&in_dev->lock); read_unlock(&in_dev->lock);
} }
static void igmp_heard_query(struct in_device *in_dev, struct igmphdr *ih, static void igmp_heard_query(struct in_device *in_dev, struct sk_buff *skb,
int len) int len)
{ {
struct igmphdr *ih = skb->h.igmph;
struct igmpv3_query *ih3 = (struct igmpv3_query *)ih; struct igmpv3_query *ih3 = (struct igmpv3_query *)ih;
struct ip_mc_list *im; struct ip_mc_list *im;
u32 group = ih->group; u32 group = ih->group;
...@@ -790,6 +791,17 @@ static void igmp_heard_query(struct in_device *in_dev, struct igmphdr *ih, ...@@ -790,6 +791,17 @@ static void igmp_heard_query(struct in_device *in_dev, struct igmphdr *ih,
} else if (len < 12) { } else if (len < 12) {
return; /* ignore bogus packet; freed by caller */ return; /* ignore bogus packet; freed by caller */
} else { /* v3 */ } else { /* v3 */
if (!pskb_may_pull(skb, sizeof(struct igmpv3_query)))
return;
ih3 = (struct igmpv3_query *) skb->h.raw;
if (ih3->nsrcs) {
if (!pskb_may_pull(skb, sizeof(struct igmpv3_query)
+ ntohs(ih3->nsrcs)*sizeof(__u32)))
return;
ih3 = (struct igmpv3_query *) skb->h.raw;
}
max_delay = IGMPV3_MRC(ih3->code)*(HZ/IGMP_TIMER_SCALE); max_delay = IGMPV3_MRC(ih3->code)*(HZ/IGMP_TIMER_SCALE);
if (!max_delay) if (!max_delay)
max_delay = 1; /* can't mod w/ 0 */ max_delay = 1; /* can't mod w/ 0 */
...@@ -838,7 +850,7 @@ static void igmp_heard_query(struct in_device *in_dev, struct igmphdr *ih, ...@@ -838,7 +850,7 @@ static void igmp_heard_query(struct in_device *in_dev, struct igmphdr *ih,
int igmp_rcv(struct sk_buff *skb) int igmp_rcv(struct sk_buff *skb)
{ {
/* This basically follows the spec line by line -- see RFC1112 */ /* This basically follows the spec line by line -- see RFC1112 */
struct igmphdr *ih = skb->h.igmph; struct igmphdr *ih;
struct in_device *in_dev = in_dev_get(skb->dev); struct in_device *in_dev = in_dev_get(skb->dev);
int len = skb->len; int len = skb->len;
...@@ -847,23 +859,17 @@ int igmp_rcv(struct sk_buff *skb) ...@@ -847,23 +859,17 @@ int igmp_rcv(struct sk_buff *skb)
return 0; return 0;
} }
if (skb_is_nonlinear(skb)) { if (!pskb_may_pull(skb, sizeof(struct igmphdr)) ||
if (skb_linearize(skb, GFP_ATOMIC) != 0) { (u16)csum_fold(skb_checksum(skb, 0, len, 0))) {
kfree_skb(skb);
return -ENOMEM;
}
ih = skb->h.igmph;
}
if (len < sizeof(struct igmphdr) || ip_compute_csum((void *)ih, len)) {
in_dev_put(in_dev); in_dev_put(in_dev);
kfree_skb(skb); kfree_skb(skb);
return 0; return 0;
} }
ih = skb->h.igmph;
switch (ih->type) { switch (ih->type) {
case IGMP_HOST_MEMBERSHIP_QUERY: case IGMP_HOST_MEMBERSHIP_QUERY:
igmp_heard_query(in_dev, ih, len); igmp_heard_query(in_dev, skb, len);
break; break;
case IGMP_HOST_MEMBERSHIP_REPORT: case IGMP_HOST_MEMBERSHIP_REPORT:
case IGMPV2_HOST_MEMBERSHIP_REPORT: case IGMPV2_HOST_MEMBERSHIP_REPORT:
......
...@@ -83,13 +83,13 @@ static int maxvif; ...@@ -83,13 +83,13 @@ static int maxvif;
#define VIF_EXISTS(idx) (vif_table[idx].dev != NULL) #define VIF_EXISTS(idx) (vif_table[idx].dev != NULL)
int mroute_do_assert; /* Set in PIM assert */ static int mroute_do_assert; /* Set in PIM assert */
int mroute_do_pim; static int mroute_do_pim;
static struct mfc_cache *mfc_cache_array[MFC_LINES]; /* Forwarding cache */ static struct mfc_cache *mfc_cache_array[MFC_LINES]; /* Forwarding cache */
static struct mfc_cache *mfc_unres_queue; /* Queue of unresolved entries */ static struct mfc_cache *mfc_unres_queue; /* Queue of unresolved entries */
atomic_t cache_resolve_queue_len; /* Size of unresolved */ static atomic_t cache_resolve_queue_len; /* Size of unresolved */
/* Special spinlock for queue of unresolved entries */ /* Special spinlock for queue of unresolved entries */
static spinlock_t mfc_unres_lock = SPIN_LOCK_UNLOCKED; static spinlock_t mfc_unres_lock = SPIN_LOCK_UNLOCKED;
...@@ -102,7 +102,7 @@ static spinlock_t mfc_unres_lock = SPIN_LOCK_UNLOCKED; ...@@ -102,7 +102,7 @@ static spinlock_t mfc_unres_lock = SPIN_LOCK_UNLOCKED;
In this case data path is free of exclusive locks at all. In this case data path is free of exclusive locks at all.
*/ */
kmem_cache_t *mrt_cachep; static kmem_cache_t *mrt_cachep;
static int ip_mr_forward(struct sk_buff *skb, struct mfc_cache *cache, int local); static int ip_mr_forward(struct sk_buff *skb, struct mfc_cache *cache, int local);
static int ipmr_cache_report(struct sk_buff *pkt, vifi_t vifi, int assert); static int ipmr_cache_report(struct sk_buff *pkt, vifi_t vifi, int assert);
...@@ -158,6 +158,10 @@ struct net_device *ipmr_new_tunnel(struct vifctl *v) ...@@ -158,6 +158,10 @@ struct net_device *ipmr_new_tunnel(struct vifctl *v)
return dev; return dev;
failure: failure:
/* allow the register to be completed before unregistering. */
rtnl_unlock();
rtnl_lock();
unregister_netdevice(dev); unregister_netdevice(dev);
return NULL; return NULL;
} }
...@@ -182,35 +186,23 @@ static struct net_device_stats *reg_vif_get_stats(struct net_device *dev) ...@@ -182,35 +186,23 @@ static struct net_device_stats *reg_vif_get_stats(struct net_device *dev)
return (struct net_device_stats*)dev->priv; return (struct net_device_stats*)dev->priv;
} }
static void vif_dev_destructor(struct net_device *dev) static void reg_vif_setup(struct net_device *dev)
{
kfree(dev);
}
static
struct net_device *ipmr_reg_vif(struct vifctl *v)
{ {
struct net_device *dev;
struct in_device *in_dev;
int size;
size = sizeof(*dev) + sizeof(struct net_device_stats);
dev = kmalloc(size, GFP_KERNEL);
if (!dev)
return NULL;
memset(dev, 0, size);
dev->priv = dev + 1;
strcpy(dev->name, "pimreg");
dev->type = ARPHRD_PIMREG; dev->type = ARPHRD_PIMREG;
dev->mtu = 1500 - sizeof(struct iphdr) - 8; dev->mtu = 1500 - sizeof(struct iphdr) - 8;
dev->flags = IFF_NOARP; dev->flags = IFF_NOARP;
dev->hard_start_xmit = reg_vif_xmit; dev->hard_start_xmit = reg_vif_xmit;
dev->get_stats = reg_vif_get_stats; dev->get_stats = reg_vif_get_stats;
dev->destructor = vif_dev_destructor; dev->destructor = (void (*)(struct net_device *)) kfree;
}
static struct net_device *ipmr_reg_vif(void)
{
struct net_device *dev;
struct in_device *in_dev;
dev = alloc_netdev(sizeof(struct net_device_stats), "pimreg",
reg_vif_setup);
if (register_netdevice(dev)) { if (register_netdevice(dev)) {
kfree(dev); kfree(dev);
...@@ -229,6 +221,10 @@ struct net_device *ipmr_reg_vif(struct vifctl *v) ...@@ -229,6 +221,10 @@ struct net_device *ipmr_reg_vif(struct vifctl *v)
return dev; return dev;
failure: failure:
/* allow the register to be completed before unregistering. */
rtnl_unlock();
rtnl_lock();
unregister_netdevice(dev); unregister_netdevice(dev);
return NULL; return NULL;
} }
...@@ -316,7 +312,7 @@ static void ipmr_destroy_unres(struct mfc_cache *c) ...@@ -316,7 +312,7 @@ static void ipmr_destroy_unres(struct mfc_cache *c)
/* Single timer process for all the unresolved queue. */ /* Single timer process for all the unresolved queue. */
void ipmr_expire_process(unsigned long dummy) static void ipmr_expire_process(unsigned long dummy)
{ {
unsigned long now; unsigned long now;
unsigned long expires; unsigned long expires;
...@@ -335,9 +331,8 @@ void ipmr_expire_process(unsigned long dummy) ...@@ -335,9 +331,8 @@ void ipmr_expire_process(unsigned long dummy)
cp = &mfc_unres_queue; cp = &mfc_unres_queue;
while ((c=*cp) != NULL) { while ((c=*cp) != NULL) {
long interval = c->mfc_un.unres.expires - now; if (time_after(c->mfc_un.unres.expires, now)) {
unsigned long interval = c->mfc_un.unres.expires - now;
if (interval > 0) {
if (interval < expires) if (interval < expires)
expires = interval; expires = interval;
cp = &c->next; cp = &c->next;
...@@ -397,7 +392,7 @@ static int vif_add(struct vifctl *vifc, int mrtsock) ...@@ -397,7 +392,7 @@ static int vif_add(struct vifctl *vifc, int mrtsock)
*/ */
if (reg_vif_num >= 0) if (reg_vif_num >= 0)
return -EADDRINUSE; return -EADDRINUSE;
dev = ipmr_reg_vif(vifc); dev = ipmr_reg_vif();
if (!dev) if (!dev)
return -ENOBUFS; return -ENOBUFS;
break; break;
...@@ -683,7 +678,7 @@ ipmr_cache_unresolved(vifi_t vifi, struct sk_buff *skb) ...@@ -683,7 +678,7 @@ ipmr_cache_unresolved(vifi_t vifi, struct sk_buff *skb)
* MFC cache manipulation by user space mroute daemon * MFC cache manipulation by user space mroute daemon
*/ */
int ipmr_mfc_delete(struct mfcctl *mfc) static int ipmr_mfc_delete(struct mfcctl *mfc)
{ {
int line; int line;
struct mfc_cache *c, **cp; struct mfc_cache *c, **cp;
...@@ -704,7 +699,7 @@ int ipmr_mfc_delete(struct mfcctl *mfc) ...@@ -704,7 +699,7 @@ int ipmr_mfc_delete(struct mfcctl *mfc)
return -ENOENT; return -ENOENT;
} }
int ipmr_mfc_add(struct mfcctl *mfc, int mrtsock) static int ipmr_mfc_add(struct mfcctl *mfc, int mrtsock)
{ {
int line; int line;
struct mfc_cache *uc, *c, **cp; struct mfc_cache *uc, *c, **cp;
...@@ -1078,9 +1073,7 @@ static int ipmr_device_event(struct notifier_block *this, unsigned long event, v ...@@ -1078,9 +1073,7 @@ static int ipmr_device_event(struct notifier_block *this, unsigned long event, v
static struct notifier_block ip_mr_notifier={ static struct notifier_block ip_mr_notifier={
ipmr_device_event, .notifier_call = ipmr_device_event,
NULL,
0
}; };
/* /*
...@@ -1234,7 +1227,7 @@ static void ipmr_queue_xmit(struct sk_buff *skb, struct mfc_cache *c, ...@@ -1234,7 +1227,7 @@ static void ipmr_queue_xmit(struct sk_buff *skb, struct mfc_cache *c,
ipmr_forward_finish); ipmr_forward_finish);
} }
int ipmr_find_vif(struct net_device *dev) static int ipmr_find_vif(struct net_device *dev)
{ {
int ct; int ct;
for (ct=maxvif-1; ct>=0; ct--) { for (ct=maxvif-1; ct>=0; ct--) {
...@@ -1246,7 +1239,7 @@ int ipmr_find_vif(struct net_device *dev) ...@@ -1246,7 +1239,7 @@ int ipmr_find_vif(struct net_device *dev)
/* "local" means that we should preserve one skb (for local delivery) */ /* "local" means that we should preserve one skb (for local delivery) */
int ip_mr_forward(struct sk_buff *skb, struct mfc_cache *cache, int local) static int ip_mr_forward(struct sk_buff *skb, struct mfc_cache *cache, int local)
{ {
int psend = -1; int psend = -1;
int vif, ct; int vif, ct;
...@@ -1286,7 +1279,8 @@ int ip_mr_forward(struct sk_buff *skb, struct mfc_cache *cache, int local) ...@@ -1286,7 +1279,8 @@ int ip_mr_forward(struct sk_buff *skb, struct mfc_cache *cache, int local)
large chunk of pimd to kernel. Ough... --ANK large chunk of pimd to kernel. Ough... --ANK
*/ */
(mroute_do_pim || cache->mfc_un.res.ttls[true_vifi] < 255) && (mroute_do_pim || cache->mfc_un.res.ttls[true_vifi] < 255) &&
jiffies - cache->mfc_un.res.last_assert > MFC_ASSERT_THRESH) { time_after(jiffies,
cache->mfc_un.res.last_assert + MFC_ASSERT_THRESH)) {
cache->mfc_un.res.last_assert = jiffies; cache->mfc_un.res.last_assert = jiffies;
ipmr_cache_report(skb, true_vifi, IGMPMSG_WRONGVIF); ipmr_cache_report(skb, true_vifi, IGMPMSG_WRONGVIF);
} }
...@@ -1406,24 +1400,19 @@ int ip_mr_input(struct sk_buff *skb) ...@@ -1406,24 +1400,19 @@ int ip_mr_input(struct sk_buff *skb)
int pim_rcv_v1(struct sk_buff * skb) int pim_rcv_v1(struct sk_buff * skb)
{ {
struct igmphdr *pim = (struct igmphdr*)skb->h.raw; struct igmphdr *pim;
struct iphdr *encap; struct iphdr *encap;
struct net_device *reg_dev = NULL; struct net_device *reg_dev = NULL;
if (skb_is_nonlinear(skb)) { if (!pskb_may_pull(skb, sizeof(*pim) + sizeof(*encap)))
if (skb_linearize(skb, GFP_ATOMIC) != 0) { goto drop;
kfree_skb(skb);
return -ENOMEM; pim = (struct igmphdr*)skb->h.raw;
}
pim = (struct igmphdr*)skb->h.raw;
}
if (!mroute_do_pim || if (!mroute_do_pim ||
skb->len < sizeof(*pim) + sizeof(*encap) || skb->len < sizeof(*pim) + sizeof(*encap) ||
pim->group != PIM_V1_VERSION || pim->code != PIM_V1_REGISTER) { pim->group != PIM_V1_VERSION || pim->code != PIM_V1_REGISTER)
kfree_skb(skb); goto drop;
return -EINVAL;
}
encap = (struct iphdr*)(skb->h.raw + sizeof(struct igmphdr)); encap = (struct iphdr*)(skb->h.raw + sizeof(struct igmphdr));
/* /*
...@@ -1433,11 +1422,9 @@ int pim_rcv_v1(struct sk_buff * skb) ...@@ -1433,11 +1422,9 @@ int pim_rcv_v1(struct sk_buff * skb)
c. packet is not truncated c. packet is not truncated
*/ */
if (!MULTICAST(encap->daddr) || if (!MULTICAST(encap->daddr) ||
ntohs(encap->tot_len) == 0 || encap->tot_len == 0 ||
ntohs(encap->tot_len) + sizeof(*pim) > skb->len) { ntohs(encap->tot_len) + sizeof(*pim) > skb->len)
kfree_skb(skb); goto drop;
return -EINVAL;
}
read_lock(&mrt_lock); read_lock(&mrt_lock);
if (reg_vif_num >= 0) if (reg_vif_num >= 0)
...@@ -1446,10 +1433,8 @@ int pim_rcv_v1(struct sk_buff * skb) ...@@ -1446,10 +1433,8 @@ int pim_rcv_v1(struct sk_buff * skb)
dev_hold(reg_dev); dev_hold(reg_dev);
read_unlock(&mrt_lock); read_unlock(&mrt_lock);
if (reg_dev == NULL) { if (reg_dev == NULL)
kfree_skb(skb); goto drop;
return -EINVAL;
}
skb->mac.raw = skb->nh.raw; skb->mac.raw = skb->nh.raw;
skb_pull(skb, (u8*)encap - skb->data); skb_pull(skb, (u8*)encap - skb->data);
...@@ -1470,41 +1455,35 @@ int pim_rcv_v1(struct sk_buff * skb) ...@@ -1470,41 +1455,35 @@ int pim_rcv_v1(struct sk_buff * skb)
netif_rx(skb); netif_rx(skb);
dev_put(reg_dev); dev_put(reg_dev);
return 0; return 0;
drop:
kfree_skb(skb);
return 0;
} }
#endif #endif
#ifdef CONFIG_IP_PIMSM_V2 #ifdef CONFIG_IP_PIMSM_V2
int pim_rcv(struct sk_buff * skb) static int pim_rcv(struct sk_buff * skb)
{ {
struct pimreghdr *pim = (struct pimreghdr*)skb->h.raw; struct pimreghdr *pim;
struct iphdr *encap; struct iphdr *encap;
struct net_device *reg_dev = NULL; struct net_device *reg_dev = NULL;
if (skb_is_nonlinear(skb)) { if (!pskb_may_pull(skb, sizeof(*pim) + sizeof(*encap)))
if (skb_linearize(skb, GFP_ATOMIC) != 0) { goto drop;
kfree_skb(skb);
return -ENOMEM;
}
pim = (struct pimreghdr*)skb->h.raw;
}
if (skb->len < sizeof(*pim) + sizeof(*encap) || pim = (struct pimreghdr*)skb->h.raw;
pim->type != ((PIM_VERSION<<4)|(PIM_REGISTER)) || if (pim->type != ((PIM_VERSION<<4)|(PIM_REGISTER)) ||
(pim->flags&PIM_NULL_REGISTER) || (pim->flags&PIM_NULL_REGISTER) ||
(ip_compute_csum((void *)pim, sizeof(*pim)) != 0 && (ip_compute_csum((void *)pim, sizeof(*pim)) != 0 &&
ip_compute_csum((void *)pim, skb->len))) { (u16)csum_fold(skb_checksum(skb, 0, skb->len, 0))))
kfree_skb(skb); goto drop;
return -EINVAL;
}
/* check if the inner packet is destined to mcast group */ /* check if the inner packet is destined to mcast group */
encap = (struct iphdr*)(skb->h.raw + sizeof(struct pimreghdr)); encap = (struct iphdr*)(skb->h.raw + sizeof(struct pimreghdr));
if (!MULTICAST(encap->daddr) || if (!MULTICAST(encap->daddr) ||
ntohs(encap->tot_len) == 0 || encap->tot_len == 0 ||
ntohs(encap->tot_len) + sizeof(*pim) > skb->len) { ntohs(encap->tot_len) + sizeof(*pim) > skb->len)
kfree_skb(skb); goto drop;
return -EINVAL;
}
read_lock(&mrt_lock); read_lock(&mrt_lock);
if (reg_vif_num >= 0) if (reg_vif_num >= 0)
...@@ -1513,10 +1492,8 @@ int pim_rcv(struct sk_buff * skb) ...@@ -1513,10 +1492,8 @@ int pim_rcv(struct sk_buff * skb)
dev_hold(reg_dev); dev_hold(reg_dev);
read_unlock(&mrt_lock); read_unlock(&mrt_lock);
if (reg_dev == NULL) { if (reg_dev == NULL)
kfree_skb(skb); goto drop;
return -EINVAL;
}
skb->mac.raw = skb->nh.raw; skb->mac.raw = skb->nh.raw;
skb_pull(skb, (u8*)encap - skb->data); skb_pull(skb, (u8*)encap - skb->data);
...@@ -1537,6 +1514,9 @@ int pim_rcv(struct sk_buff * skb) ...@@ -1537,6 +1514,9 @@ int pim_rcv(struct sk_buff * skb)
netif_rx(skb); netif_rx(skb);
dev_put(reg_dev); dev_put(reg_dev);
return 0; return 0;
drop:
kfree_skb(skb);
return 0;
} }
#endif #endif
......
...@@ -713,6 +713,7 @@ void ndisc_recv_ns(struct sk_buff *skb) ...@@ -713,6 +713,7 @@ void ndisc_recv_ns(struct sk_buff *skb)
struct net_device *dev = skb->dev; struct net_device *dev = skb->dev;
struct inet6_ifaddr *ifp; struct inet6_ifaddr *ifp;
struct neighbour *neigh; struct neighbour *neigh;
int addr_type = ipv6_addr_type(saddr);
if (ipv6_addr_type(&msg->target)&IPV6_ADDR_MULTICAST) { if (ipv6_addr_type(&msg->target)&IPV6_ADDR_MULTICAST) {
if (net_ratelimit()) if (net_ratelimit())
...@@ -720,6 +721,20 @@ void ndisc_recv_ns(struct sk_buff *skb) ...@@ -720,6 +721,20 @@ void ndisc_recv_ns(struct sk_buff *skb)
return; return;
} }
/*
* RFC2461 7.1.1:
* DAD has to be destined for solicited node multicast address.
*/
if (addr_type == IPV6_ADDR_ANY &&
!(daddr->s6_addr32[0] == htonl(0xff020000) &&
daddr->s6_addr32[1] == htonl(0x00000000) &&
daddr->s6_addr32[2] == htonl(0x00000001) &&
daddr->s6_addr [12] == 0xff )) {
if (net_ratelimit())
printk(KERN_DEBUG "ICMP6 NS: bad DAD packet (wrong destination)\n");
return;
}
if (!ndisc_parse_options(msg->opt, ndoptlen, &ndopts)) { if (!ndisc_parse_options(msg->opt, ndoptlen, &ndopts)) {
if (net_ratelimit()) if (net_ratelimit())
printk(KERN_WARNING "ICMP NS: invalid ND option, ignored.\n"); printk(KERN_WARNING "ICMP NS: invalid ND option, ignored.\n");
...@@ -734,23 +749,20 @@ void ndisc_recv_ns(struct sk_buff *skb) ...@@ -734,23 +749,20 @@ void ndisc_recv_ns(struct sk_buff *skb)
printk(KERN_WARNING "ICMP NS: bad lladdr length.\n"); printk(KERN_WARNING "ICMP NS: bad lladdr length.\n");
return; return;
} }
}
/* XXX: RFC2461 7.1.1: /* XXX: RFC2461 7.1.1:
* If the IP source address is the unspecified address, there * If the IP source address is the unspecified address,
* MUST NOT be source link-layer address option in the message. * there MUST NOT be source link-layer address option
* * in the message.
* NOTE! Linux kernel < 2.4.4 broke this rule. */
*/ if (addr_type == IPV6_ADDR_ANY) {
if (net_ratelimit())
/* XXX: RFC2461 7.1.1: printk(KERN_WARNING "ICMP6 NS: bad DAD packet (link-layer address option)\n");
* If the IP source address is the unspecified address, the IP return;
* destination address MUST be a solicited-node multicast address. }
*/ }
if ((ifp = ipv6_get_ifaddr(&msg->target, dev)) != NULL) { if ((ifp = ipv6_get_ifaddr(&msg->target, dev)) != NULL) {
int addr_type = ipv6_addr_type(saddr);
if (ifp->flags & IFA_F_TENTATIVE) { if (ifp->flags & IFA_F_TENTATIVE) {
/* Address is tentative. If the source /* Address is tentative. If the source
is unspecified address, it is someone is unspecified address, it is someone
...@@ -816,7 +828,6 @@ void ndisc_recv_ns(struct sk_buff *skb) ...@@ -816,7 +828,6 @@ void ndisc_recv_ns(struct sk_buff *skb)
in6_ifa_put(ifp); in6_ifa_put(ifp);
} else if (ipv6_chk_acast_addr(dev, &msg->target)) { } else if (ipv6_chk_acast_addr(dev, &msg->target)) {
struct inet6_dev *idev = in6_dev_get(dev); struct inet6_dev *idev = in6_dev_get(dev);
int addr_type = ipv6_addr_type(saddr);
/* anycast */ /* anycast */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment