source: trunk/target/linux/generic-2.6/patches-2.6.32/240-packet_socket_type.patch @ 19687

Last change on this file since 19687 was 19687, checked in by kaloz, 6 years ago

refresh generic 2.6.32 patches

File size: 3.3 KB
  • include/linux/if_packet.h

    This patch allows the user to specify desired packet types (outgoing,
    broadcast, unicast, etc.) on packet sockets via setsockopt.
    This can reduce the load in situations where only a limited number
    of packet types are necessary
    
    Signed-off-by: Felix Fietkau <nbd@openwrt.org>
    
    a b struct sockaddr_ll 
    3131/* These ones are invisible by user level */ 
    3232#define PACKET_LOOPBACK         5               /* MC/BRD frame looped back */ 
    3333#define PACKET_FASTROUTE        6               /* Fastrouted frame     */ 
     34#define PACKET_MASK_ANY         0xffffffff      /* mask for packet type bits */ 
     35 
    3436 
    3537/* Packet socket options */ 
    3638 
    struct sockaddr_ll 
    4850#define PACKET_RESERVE                  12 
    4951#define PACKET_TX_RING                  13 
    5052#define PACKET_LOSS                     14 
     53#define PACKET_RECV_TYPE                15 
    5154 
    5255struct tpacket_stats 
    5356{ 
  • net/packet/af_packet.c

    a b struct packet_sock { 
    204204        unsigned int            tp_reserve; 
    205205        unsigned int            tp_loss:1; 
    206206#endif 
     207        unsigned int            pkt_type; 
    207208}; 
    208209 
    209210struct packet_skb_cb { 
    static int packet_rcv_spkt(struct sk_buf 
    342343{ 
    343344        struct sock *sk; 
    344345        struct sockaddr_pkt *spkt; 
     346        struct packet_sock *po; 
    345347 
    346348        /* 
    347349         *      When we registered the protocol we saved the socket in the data 
    static int packet_rcv_spkt(struct sk_buf 
    349351         */ 
    350352 
    351353        sk = pt->af_packet_priv; 
     354        po = pkt_sk(sk); 
    352355 
    353356        /* 
    354357         *      Yank back the headers [hope the device set this 
    static int packet_rcv_spkt(struct sk_buf 
    361364         *      so that this procedure is noop. 
    362365         */ 
    363366 
    364         if (skb->pkt_type == PACKET_LOOPBACK) 
     367        if (!(po->pkt_type & (1 << skb->pkt_type))) 
    365368                goto out; 
    366369 
    367370        if (dev_net(dev) != sock_net(sk)) 
    static int packet_rcv(struct sk_buff *sk 
    545548        int skb_len = skb->len; 
    546549        unsigned int snaplen, res; 
    547550 
    548         if (skb->pkt_type == PACKET_LOOPBACK) 
    549                 goto drop; 
    550  
    551551        sk = pt->af_packet_priv; 
    552552        po = pkt_sk(sk); 
    553553 
     554        if (!(po->pkt_type & (1 << skb->pkt_type))) 
     555                goto drop; 
     556 
    554557        if (dev_net(dev) != sock_net(sk)) 
    555558                goto drop; 
    556559 
    static int tpacket_rcv(struct sk_buff *s 
    667670        struct timeval tv; 
    668671        struct timespec ts; 
    669672 
    670         if (skb->pkt_type == PACKET_LOOPBACK) 
    671                 goto drop; 
    672  
    673673        sk = pt->af_packet_priv; 
    674674        po = pkt_sk(sk); 
    675675 
     676        if (!(po->pkt_type & (1 << skb->pkt_type))) 
     677                goto drop; 
     678 
    676679        if (dev_net(dev) != sock_net(sk)) 
    677680                goto drop; 
    678681 
    static int packet_create(struct net *net 
    13901393        spin_lock_init(&po->bind_lock); 
    13911394        mutex_init(&po->pg_vec_lock); 
    13921395        po->prot_hook.func = packet_rcv; 
     1396        po->pkt_type = PACKET_MASK_ANY & ~(1 << PACKET_LOOPBACK); 
    13931397 
    13941398        if (sock->type == SOCK_PACKET) 
    13951399                po->prot_hook.func = packet_rcv_spkt; 
    packet_setsockopt(struct socket *sock, i 
    17371741                        ret = packet_mc_drop(sk, &mreq); 
    17381742                return ret; 
    17391743        } 
     1744        case PACKET_RECV_TYPE: 
     1745        { 
     1746                unsigned int val; 
     1747                if (optlen != sizeof(val)) 
     1748                        return -EINVAL; 
     1749                if (copy_from_user(&val, optval, sizeof(val))) 
     1750                        return -EFAULT; 
     1751                po->pkt_type = val & ~PACKET_LOOPBACK; 
     1752                return 0; 
     1753        } 
    17401754 
    17411755#ifdef CONFIG_PACKET_MMAP 
    17421756        case PACKET_RX_RING: 
    static int packet_getsockopt(struct sock 
    18821896 
    18831897                data = &val; 
    18841898                break; 
     1899        case PACKET_RECV_TYPE: 
     1900                if (len > sizeof(unsigned int)) 
     1901                        len = sizeof(unsigned int); 
     1902                val = po->pkt_type; 
     1903 
     1904                data = &val; 
     1905                break; 
    18851906#ifdef CONFIG_PACKET_MMAP 
    18861907        case PACKET_VERSION: 
    18871908                if (len > sizeof(int)) 
Note: See TracBrowser for help on using the repository browser.