From: Bob Richmond <robert.richmond@greenwavereality.com>
To: linux-kernel@vger.kernel.org
Subject: Adding neighbor cache entry solely initiated by multicast traffic
Date: Tue, 22 Jul 2014 18:53:32 -0700 [thread overview]
Message-ID: <53CF159C.8040102@greenwavereality.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 998 bytes --]
For a device on the local network that mostly functions as a multicast
receiver, the only packets a router may see from this client are IGMP
membership reports. I believe that alone should be enough information to
establish a neighbor cache entry for it.
A client intending to unicast to the router will first ARP for the
router's address, and the router will then respond to the ARP AND cache
the client's address to avoid ARPing for the client's address when
replying to original packet.
I believe this patch functions in the same spirit of that approach.
Something like this is necessary for a router managing multicast
subscriptions in userspace using the ipmr API. Such a thing would need
to know which interface an IGMP membership report came in on, in order
to establish a vif route for it. Without a netlink message indicating a
new neighbor for the subscriber's IP address, it can't be known which
vif to establish the route on.
Is there anything glaringly wrong with this?
[-- Attachment #2: linux-3.4.91_add_neighbour_on_multicast.patch --]
[-- Type: text/x-patch, Size: 1699 bytes --]
*** linux-3.4.91/net/ipv4/route.c.orig 2014-05-18 05:26:09.000000000 -0700
--- linux-3.4.91/net/ipv4/route.c 2014-07-22 17:20:03.156032862 -0700
***************
*** 2008,2031 ****
--- 2008,2033 ----
return dst_alloc(&ipv4_dst_ops, dev, 1, -1,
DST_HOST |
(nopolicy ? DST_NOPOLICY : 0) |
(noxfrm ? DST_NOXFRM : 0));
}
/* called in rcu_read_lock() section */
static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr,
u8 tos, struct net_device *dev, int our)
{
unsigned int hash;
struct rtable *rth;
+ struct neighbour *n;
+ char lladdr[8];
__be32 spec_dst;
struct in_device *in_dev = __in_dev_get_rcu(dev);
u32 itag = 0;
int err;
/* Primary sanity checks. */
if (in_dev == NULL)
return -EINVAL;
if (ipv4_is_multicast(saddr) || ipv4_is_lbcast(saddr) ||
ipv4_is_loopback(saddr) || skb->protocol != htons(ETH_P_IP))
***************
*** 2072,2095 ****
--- 2074,2101 ----
rth->dst.input= ip_local_deliver;
rth->rt_flags |= RTCF_LOCAL;
}
#ifdef CONFIG_IP_MROUTE
if (!ipv4_is_local_multicast(daddr) && IN_DEV_MFORWARD(in_dev))
rth->dst.input = ip_mr_input;
#endif
RT_CACHE_STAT_INC(in_slow_mc);
hash = rt_hash(daddr, saddr, dev->ifindex, rt_genid(dev_net(dev)));
rth = rt_intern_hash(hash, rth, skb, dev->ifindex);
+ if (dev_parse_header(skb, lladdr) > 0) {
+ n = __neigh_lookup(&arp_tbl, &saddr, dev, 1);
+ neigh_update(n, lladdr, NUD_REACHABLE, 0);
+ }
return IS_ERR(rth) ? PTR_ERR(rth) : 0;
e_nobufs:
return -ENOBUFS;
e_inval:
return -EINVAL;
e_err:
return err;
}
static void ip_handle_martian_source(struct net_device *dev,
reply other threads:[~2014-07-23 1:53 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=53CF159C.8040102@greenwavereality.com \
--to=robert.richmond@greenwavereality.com \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox