• Ilpo Järvinen's avatar
    ipmr: merge common code · b1879204
    Ilpo Järvinen authored
    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: default avatarIlpo Järvinen <ilpo.jarvinen@helsinki.fi>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    b1879204
ipmr.c 43.2 KB