ipmr: merge common code
authorIlpo Järvinen <ilpo.jarvinen@helsinki.fi>
Tue, 16 Dec 2008 09:15:11 +0000 (01:15 -0800)
committerDavid S. Miller <davem@davemloft.net>
Tue, 16 Dec 2008 09:15:11 +0000 (01:15 -0800)
commitb1879204dda06a92a4ff55b681c99ee185180003
tree3045f326dcff6bb1ca3768803bfc62e98e69c6dc
parentc40cf519f0c0f0cb0579d853949ef517a8bb494d
ipmr: merge common code

Also removes redundant skb->len < x check which can't
be true once pskb_may_pull(skb, x) succeeded.

$ diff-funcs pim_rcv ipmr.c ipmr.c pim_rcv_v1
  --- ipmr.c:pim_rcv()
  +++ ipmr.c:pim_rcv_v1()
@@ -1,22 +1,27 @@
-static int pim_rcv(struct sk_buff * skb)
+int pim_rcv_v1(struct sk_buff * skb)
 {
- struct pimreghdr *pim;
+ struct igmphdr *pim;
  struct iphdr   *encap;
  struct net_device  *reg_dev = NULL;

  if (!pskb_may_pull(skb, sizeof(*pim) + sizeof(*encap)))
  goto drop;

- pim = (struct pimreghdr *)skb_transport_header(skb);
- if (pim->type != ((PIM_VERSION<<4)|(PIM_REGISTER)) ||
-     (pim->flags&PIM_NULL_REGISTER) ||
-     (ip_compute_csum((void *)pim, sizeof(*pim)) != 0 &&
-      csum_fold(skb_checksum(skb, 0, skb->len, 0))))
+ pim = igmp_hdr(skb);
+
+ if (!mroute_do_pim ||
+     skb->len < sizeof(*pim) + sizeof(*encap) ||
+     pim->group != PIM_V1_VERSION || pim->code != PIM_V1_REGISTER)
  goto drop;

- /* check if the inner packet is destined to mcast group */
  encap = (struct iphdr *)(skb_transport_header(skb) +
-  sizeof(struct pimreghdr));
+  sizeof(struct igmphdr));
+ /*
+    Check that:
+    a. packet is really destinted to a multicast group
+    b. packet is not a NULL-REGISTER
+    c. packet is not truncated
+  */
  if (!ipv4_is_multicast(encap->daddr) ||
      encap->tot_len == 0 ||
      ntohs(encap->tot_len) + sizeof(*pim) > skb->len)
@@ -40,9 +45,9 @@
  skb->ip_summed = 0;
  skb->pkt_type = PACKET_HOST;
  dst_release(skb->dst);
+ skb->dst = NULL;
  reg_dev->stats.rx_bytes += skb->len;
  reg_dev->stats.rx_packets++;
- skb->dst = NULL;
  nf_reset(skb);
  netif_rx(skb);
  dev_put(reg_dev);

$ codiff net/ipv4/ipmr.o.old net/ipv4/ipmr.o.new

net/ipv4/ipmr.c:
  pim_rcv_v1 | -283
  pim_rcv    | -284
 2 functions changed, 567 bytes removed

net/ipv4/ipmr.c:
  __pim_rcv | +307
 1 function changed, 307 bytes added

net/ipv4/ipmr.o.new:
 3 functions changed, 307 bytes added, 567 bytes removed, diff: -260

(Tested on x86_64).

It seems that pimlen arg could be left out as well and
eq-sizedness of structs trapped with BUILD_BUG_ON but
I don't think that's more than a cosmetic flaw since there
aren't that many args anyway.

Compile tested.

Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@helsinki.fi>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/ipv4/ipmr.c