source: trunk/target/linux/generic/patches-2.6.39/630-packet_socket_type.patch @ 26691

Last change on this file since 26691 was 26691, checked in by nbd, 5 years ago

kernel: reorganize 2.6.39 patches

File size: 3.5 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 { 
    2929/* These ones are invisible by user level */ 
    3030#define PACKET_LOOPBACK         5               /* MC/BRD frame looped back */ 
    3131#define PACKET_FASTROUTE        6               /* Fastrouted frame     */ 
     32#define PACKET_MASK_ANY         0xffffffff      /* mask for packet type bits */ 
     33 
    3234 
    3335/* Packet socket options */ 
    3436 
    struct sockaddr_ll { 
    4951#define PACKET_VNET_HDR                 15 
    5052#define PACKET_TX_TIMESTAMP             16 
    5153#define PACKET_TIMESTAMP                17 
     54#define PACKET_RECV_TYPE                18 
    5255 
    5356struct tpacket_stats { 
    5457        unsigned int    tp_packets; 
  • net/packet/af_packet.c

    a b struct packet_sock { 
    210210        unsigned int            tp_loss:1; 
    211211        unsigned int            tp_tstamp; 
    212212        struct packet_type      prot_hook ____cacheline_aligned_in_smp; 
     213        unsigned int            pkt_type; 
    213214}; 
    214215 
    215216struct packet_skb_cb { 
    static int packet_rcv_spkt(struct sk_buf 
    354355{ 
    355356        struct sock *sk; 
    356357        struct sockaddr_pkt *spkt; 
     358        struct packet_sock *po; 
    357359 
    358360        /* 
    359361         *      When we registered the protocol we saved the socket in the data 
    static int packet_rcv_spkt(struct sk_buf 
    361363         */ 
    362364 
    363365        sk = pt->af_packet_priv; 
     366        po = pkt_sk(sk); 
    364367 
    365368        /* 
    366369         *      Yank back the headers [hope the device set this 
    static int packet_rcv_spkt(struct sk_buf 
    373376         *      so that this procedure is noop. 
    374377         */ 
    375378 
    376         if (skb->pkt_type == PACKET_LOOPBACK) 
     379        if (!(po->pkt_type & (1 << skb->pkt_type))) 
    377380                goto out; 
    378381 
    379382        if (!net_eq(dev_net(dev), sock_net(sk))) 
    static int packet_rcv(struct sk_buff *sk 
    566569        int skb_len = skb->len; 
    567570        unsigned int snaplen, res; 
    568571 
    569         if (skb->pkt_type == PACKET_LOOPBACK) 
    570                 goto drop; 
    571  
    572572        sk = pt->af_packet_priv; 
    573573        po = pkt_sk(sk); 
    574574 
     575        if (!(po->pkt_type & (1 << skb->pkt_type))) 
     576                goto drop; 
     577 
    575578        if (!net_eq(dev_net(dev), sock_net(sk))) 
    576579                goto drop; 
    577580 
    static int tpacket_rcv(struct sk_buff *s 
    687690        struct timespec ts; 
    688691        struct skb_shared_hwtstamps *shhwtstamps = skb_hwtstamps(skb); 
    689692 
    690         if (skb->pkt_type == PACKET_LOOPBACK) 
    691                 goto drop; 
    692  
    693693        sk = pt->af_packet_priv; 
    694694        po = pkt_sk(sk); 
    695695 
     696        if (!(po->pkt_type & (1 << skb->pkt_type))) 
     697                goto drop; 
     698 
    696699        if (!net_eq(dev_net(dev), sock_net(sk))) 
    697700                goto drop; 
    698701 
    static int packet_create(struct net *net 
    15231526        spin_lock_init(&po->bind_lock); 
    15241527        mutex_init(&po->pg_vec_lock); 
    15251528        po->prot_hook.func = packet_rcv; 
     1529        po->pkt_type = PACKET_MASK_ANY & ~(1 << PACKET_LOOPBACK); 
    15261530 
    15271531        if (sock->type == SOCK_PACKET) 
    15281532                po->prot_hook.func = packet_rcv_spkt; 
    packet_setsockopt(struct socket *sock, i 
    20912095                po->tp_tstamp = val; 
    20922096                return 0; 
    20932097        } 
     2098        case PACKET_RECV_TYPE: 
     2099        { 
     2100                unsigned int val; 
     2101                if (optlen != sizeof(val)) 
     2102                        return -EINVAL; 
     2103                if (copy_from_user(&val, optval, sizeof(val))) 
     2104                        return -EFAULT; 
     2105                po->pkt_type = val & ~PACKET_LOOPBACK; 
     2106                return 0; 
     2107        } 
    20942108        default: 
    20952109                return -ENOPROTOOPT; 
    20962110        } 
    static int packet_getsockopt(struct sock 
    21482162 
    21492163                data = &val; 
    21502164                break; 
     2165        case PACKET_RECV_TYPE: 
     2166                if (len > sizeof(unsigned int)) 
     2167                        len = sizeof(unsigned int); 
     2168                val = po->pkt_type; 
     2169 
     2170                data = &val; 
     2171                break; 
    21512172        case PACKET_VERSION: 
    21522173                if (len > sizeof(int)) 
    21532174                        len = sizeof(int); 
Note: See TracBrowser for help on using the repository browser.