Commit 5f6e4c74 authored by David S. Miller's avatar David S. Miller

Merge nuts.ninka.net:/home/davem/src/BK/network-2.5

into nuts.ninka.net:/home/davem/src/BK/net-2.5
parents c39d4913 4a9b943d
...@@ -547,7 +547,9 @@ static struct net_device *register_vlan_device(const char *eth_IF_name, ...@@ -547,7 +547,9 @@ static struct net_device *register_vlan_device(const char *eth_IF_name,
grp->vlan_devices[VLAN_ID] = new_dev; grp->vlan_devices[VLAN_ID] = new_dev;
vlan_proc_add_dev(new_dev); /* create it's proc entry */ if (vlan_proc_add_dev(new_dev)<0)/* create it's proc entry */
printk(KERN_WARNING "VLAN: failed to add proc entry for %s\n",
new_dev->name);
if (real_dev->features & NETIF_F_HW_VLAN_FILTER) if (real_dev->features & NETIF_F_HW_VLAN_FILTER)
real_dev->vlan_rx_add_vid(real_dev, VLAN_ID); real_dev->vlan_rx_add_vid(real_dev, VLAN_ID);
......
...@@ -228,8 +228,10 @@ int vlan_proc_rem_dev(struct net_device *vlandev) ...@@ -228,8 +228,10 @@ int vlan_proc_rem_dev(struct net_device *vlandev)
#endif #endif
/** NOTE: This will consume the memory pointed to by dent, it seems. */ /** NOTE: This will consume the memory pointed to by dent, it seems. */
if (VLAN_DEV_INFO(vlandev)->dent) {
remove_proc_entry(VLAN_DEV_INFO(vlandev)->dent->name, proc_vlan_dir); remove_proc_entry(VLAN_DEV_INFO(vlandev)->dent->name, proc_vlan_dir);
VLAN_DEV_INFO(vlandev)->dent = NULL; VLAN_DEV_INFO(vlandev)->dent = NULL;
}
return 0; return 0;
} }
......
...@@ -373,7 +373,7 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ip_mc_list *pmc, ...@@ -373,7 +373,7 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ip_mc_list *pmc,
struct net_device *dev = pmc->interface->dev; struct net_device *dev = pmc->interface->dev;
struct igmpv3_report *pih; struct igmpv3_report *pih;
struct igmpv3_grec *pgr = 0; struct igmpv3_grec *pgr = 0;
struct ip_sf_list *psf, *psf_next, *psf_prev, *psf_list; struct ip_sf_list *psf, *psf_next, *psf_prev, **psf_list;
int scount, first, isquery, truncate; int scount, first, isquery, truncate;
if (pmc->multiaddr == IGMP_ALL_HOSTS) if (pmc->multiaddr == IGMP_ALL_HOSTS)
...@@ -384,9 +384,9 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ip_mc_list *pmc, ...@@ -384,9 +384,9 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ip_mc_list *pmc,
truncate = type == IGMPV3_MODE_IS_EXCLUDE || truncate = type == IGMPV3_MODE_IS_EXCLUDE ||
type == IGMPV3_CHANGE_TO_EXCLUDE; type == IGMPV3_CHANGE_TO_EXCLUDE;
psf_list = sdeleted ? pmc->tomb : pmc->sources; psf_list = sdeleted ? &pmc->tomb : &pmc->sources;
if (!psf_list) { if (!*psf_list) {
if (type == IGMPV3_ALLOW_NEW_SOURCES || if (type == IGMPV3_ALLOW_NEW_SOURCES ||
type == IGMPV3_BLOCK_OLD_SOURCES) type == IGMPV3_BLOCK_OLD_SOURCES)
return skb; return skb;
...@@ -417,7 +417,7 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ip_mc_list *pmc, ...@@ -417,7 +417,7 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ip_mc_list *pmc,
first = 1; first = 1;
scount = 0; scount = 0;
psf_prev = 0; psf_prev = 0;
for (psf=psf_list; psf; psf=psf_next) { for (psf=*psf_list; psf; psf=psf_next) {
u32 *psrc; u32 *psrc;
psf_next = psf->sf_next; psf_next = psf->sf_next;
...@@ -457,7 +457,7 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ip_mc_list *pmc, ...@@ -457,7 +457,7 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ip_mc_list *pmc,
if (psf_prev) if (psf_prev)
psf_prev->sf_next = psf->sf_next; psf_prev->sf_next = psf->sf_next;
else else
pmc->tomb = psf->sf_next; *psf_list = psf->sf_next;
kfree(psf); kfree(psf);
continue; continue;
} }
......
...@@ -659,10 +659,10 @@ static void igmp6_group_dropped(struct ifmcaddr6 *mc) ...@@ -659,10 +659,10 @@ static void igmp6_group_dropped(struct ifmcaddr6 *mc)
if (ndisc_mc_map(&mc->mca_addr, buf, dev, 0) == 0) if (ndisc_mc_map(&mc->mca_addr, buf, dev, 0) == 0)
dev_mc_delete(dev, buf, dev->addr_len, 0); dev_mc_delete(dev, buf, dev->addr_len, 0);
} }
spin_unlock_bh(&mc->mca_lock);
if (mc->mca_flags & MAF_NOREPORT) if (mc->mca_flags & MAF_NOREPORT)
goto done; goto done;
spin_unlock_bh(&mc->mca_lock);
if (dev->flags&IFF_UP) if (dev->flags&IFF_UP)
igmp6_leave_group(mc); igmp6_leave_group(mc);
...@@ -670,10 +670,9 @@ static void igmp6_group_dropped(struct ifmcaddr6 *mc) ...@@ -670,10 +670,9 @@ static void igmp6_group_dropped(struct ifmcaddr6 *mc)
spin_lock_bh(&mc->mca_lock); spin_lock_bh(&mc->mca_lock);
if (del_timer(&mc->mca_timer)) if (del_timer(&mc->mca_timer))
atomic_dec(&mc->mca_refcnt); atomic_dec(&mc->mca_refcnt);
spin_unlock_bh(&mc->mca_lock);
done: done:
ip6_mc_clear_src(mc); ip6_mc_clear_src(mc);
spin_unlock_bh(&mc->mca_lock);
} }
/* /*
...@@ -1307,7 +1306,7 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ifmcaddr6 *pmc, ...@@ -1307,7 +1306,7 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ifmcaddr6 *pmc,
struct net_device *dev = pmc->idev->dev; struct net_device *dev = pmc->idev->dev;
struct mld2_report *pmr; struct mld2_report *pmr;
struct mld2_grec *pgr = 0; struct mld2_grec *pgr = 0;
struct ip6_sf_list *psf, *psf_next, *psf_prev, *psf_list; struct ip6_sf_list *psf, *psf_next, *psf_prev, **psf_list;
int scount, first, isquery, truncate; int scount, first, isquery, truncate;
if (pmc->mca_flags & MAF_NOREPORT) if (pmc->mca_flags & MAF_NOREPORT)
...@@ -1318,9 +1317,9 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ifmcaddr6 *pmc, ...@@ -1318,9 +1317,9 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ifmcaddr6 *pmc,
truncate = type == MLD2_MODE_IS_EXCLUDE || truncate = type == MLD2_MODE_IS_EXCLUDE ||
type == MLD2_CHANGE_TO_EXCLUDE; type == MLD2_CHANGE_TO_EXCLUDE;
psf_list = sdeleted ? pmc->mca_tomb : pmc->mca_sources; psf_list = sdeleted ? &pmc->mca_tomb : &pmc->mca_sources;
if (!psf_list) { if (!*psf_list) {
if (type == MLD2_ALLOW_NEW_SOURCES || if (type == MLD2_ALLOW_NEW_SOURCES ||
type == MLD2_BLOCK_OLD_SOURCES) type == MLD2_BLOCK_OLD_SOURCES)
return skb; return skb;
...@@ -1351,7 +1350,7 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ifmcaddr6 *pmc, ...@@ -1351,7 +1350,7 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ifmcaddr6 *pmc,
first = 1; first = 1;
scount = 0; scount = 0;
psf_prev = 0; psf_prev = 0;
for (psf=psf_list; psf; psf=psf_next) { for (psf=*psf_list; psf; psf=psf_next) {
struct in6_addr *psrc; struct in6_addr *psrc;
psf_next = psf->sf_next; psf_next = psf->sf_next;
...@@ -1391,7 +1390,7 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ifmcaddr6 *pmc, ...@@ -1391,7 +1390,7 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ifmcaddr6 *pmc,
if (psf_prev) if (psf_prev)
psf_prev->sf_next = psf->sf_next; psf_prev->sf_next = psf->sf_next;
else else
pmc->mca_tomb = psf->sf_next; *psf_list = psf->sf_next;
kfree(psf); kfree(psf);
continue; continue;
} }
...@@ -1667,11 +1666,11 @@ int ip6_mc_del_src(struct inet6_dev *idev, struct in6_addr *pmca, int sfmode, ...@@ -1667,11 +1666,11 @@ int ip6_mc_del_src(struct inet6_dev *idev, struct in6_addr *pmca, int sfmode,
return -ESRCH; return -ESRCH;
} }
spin_lock_bh(&pmc->mca_lock); spin_lock_bh(&pmc->mca_lock);
read_unlock_bh(&idev->lock);
sf_markstate(pmc); sf_markstate(pmc);
if (!delta) { if (!delta) {
if (!pmc->mca_sfcount[sfmode]) { if (!pmc->mca_sfcount[sfmode]) {
spin_unlock_bh(&pmc->mca_lock); spin_unlock_bh(&pmc->mca_lock);
read_unlock_bh(&idev->lock);
return -EINVAL; return -EINVAL;
} }
pmc->mca_sfcount[sfmode]--; pmc->mca_sfcount[sfmode]--;
...@@ -1699,6 +1698,7 @@ int ip6_mc_del_src(struct inet6_dev *idev, struct in6_addr *pmca, int sfmode, ...@@ -1699,6 +1698,7 @@ int ip6_mc_del_src(struct inet6_dev *idev, struct in6_addr *pmca, int sfmode,
} else if (sf_setstate(pmc) || changerec) } else if (sf_setstate(pmc) || changerec)
mld_ifc_event(pmc->idev); mld_ifc_event(pmc->idev);
spin_unlock_bh(&pmc->mca_lock); spin_unlock_bh(&pmc->mca_lock);
read_unlock_bh(&idev->lock);
return err; return err;
} }
...@@ -1790,7 +1790,6 @@ int ip6_mc_add_src(struct inet6_dev *idev, struct in6_addr *pmca, int sfmode, ...@@ -1790,7 +1790,6 @@ int ip6_mc_add_src(struct inet6_dev *idev, struct in6_addr *pmca, int sfmode,
return -ESRCH; return -ESRCH;
} }
spin_lock_bh(&pmc->mca_lock); spin_lock_bh(&pmc->mca_lock);
read_unlock_bh(&idev->lock);
sf_markstate(pmc); sf_markstate(pmc);
isexclude = pmc->mca_sfmode == MCAST_EXCLUDE; isexclude = pmc->mca_sfmode == MCAST_EXCLUDE;
...@@ -1827,6 +1826,7 @@ int ip6_mc_add_src(struct inet6_dev *idev, struct in6_addr *pmca, int sfmode, ...@@ -1827,6 +1826,7 @@ int ip6_mc_add_src(struct inet6_dev *idev, struct in6_addr *pmca, int sfmode,
} else if (sf_setstate(pmc)) } else if (sf_setstate(pmc))
mld_ifc_event(idev); mld_ifc_event(idev);
spin_unlock_bh(&pmc->mca_lock); spin_unlock_bh(&pmc->mca_lock);
read_unlock_bh(&idev->lock);
return err; return err;
} }
......
...@@ -485,7 +485,7 @@ static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh, ...@@ -485,7 +485,7 @@ static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
msg->icmph.icmp6_override = !!override; msg->icmph.icmp6_override = !!override;
/* Set the target address. */ /* Set the target address. */
ipv6_addr_copy(&msg->target, src_addr); ipv6_addr_copy(&msg->target, solicited_addr);
if (inc_opt) if (inc_opt)
ndisc_fill_option(msg->opt, ND_OPT_TARGET_LL_ADDR, dev->dev_addr, dev->addr_len); ndisc_fill_option(msg->opt, ND_OPT_TARGET_LL_ADDR, dev->dev_addr, dev->addr_len);
...@@ -861,7 +861,8 @@ static void ndisc_recv_ns(struct sk_buff *skb) ...@@ -861,7 +861,8 @@ static void ndisc_recv_ns(struct sk_buff *skb)
struct inet6_dev *in6_dev = in6_dev_get(dev); struct inet6_dev *in6_dev = in6_dev_get(dev);
if (in6_dev && in6_dev->cnf.forwarding && if (in6_dev && in6_dev->cnf.forwarding &&
(addr_type & IPV6_ADDR_UNICAST) && (addr_type & IPV6_ADDR_UNICAST ||
addr_type == IPV6_ADDR_ANY) &&
pneigh_lookup(&nd_tbl, &msg->target, dev, 0)) { pneigh_lookup(&nd_tbl, &msg->target, dev, 0)) {
int inc = ipv6_addr_type(daddr)&IPV6_ADDR_MULTICAST; int inc = ipv6_addr_type(daddr)&IPV6_ADDR_MULTICAST;
...@@ -874,6 +875,7 @@ static void ndisc_recv_ns(struct sk_buff *skb) ...@@ -874,6 +875,7 @@ static void ndisc_recv_ns(struct sk_buff *skb)
else else
nd_tbl.stats.rcv_probes_ucast++; nd_tbl.stats.rcv_probes_ucast++;
if (addr_type & IPV6_ADDR_UNICAST) {
neigh = neigh_event_ns(&nd_tbl, lladdr, saddr, dev); neigh = neigh_event_ns(&nd_tbl, lladdr, saddr, dev);
if (neigh) { if (neigh) {
...@@ -881,6 +883,13 @@ static void ndisc_recv_ns(struct sk_buff *skb) ...@@ -881,6 +883,13 @@ static void ndisc_recv_ns(struct sk_buff *skb)
0, 1, 0, 1); 0, 1, 0, 1);
neigh_release(neigh); neigh_release(neigh);
} }
} else {
/* proxy should also protect against DAD */
struct in6_addr maddr;
ipv6_addr_all_nodes(&maddr);
ndisc_send_na(dev, NULL, &maddr, &msg->target,
0, 0, 0, 1);
}
} else { } else {
struct sk_buff *n = skb_clone(skb, GFP_ATOMIC); struct sk_buff *n = skb_clone(skb, GFP_ATOMIC);
if (n) if (n)
......
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