root/net/netfilter/ipset/ip_set_hash_mac.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. hash_mac4_data_equal
  2. hash_mac4_data_list
  3. hash_mac4_data_next
  4. hash_mac4_kadt
  5. hash_mac4_uadt
  6. hash_mac_init
  7. hash_mac_fini

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /* Copyright (C) 2014 Jozsef Kadlecsik <kadlec@netfilter.org> */
   3 
   4 /* Kernel module implementing an IP set type: the hash:mac type */
   5 
   6 #include <linux/jhash.h>
   7 #include <linux/module.h>
   8 #include <linux/etherdevice.h>
   9 #include <linux/skbuff.h>
  10 #include <linux/errno.h>
  11 #include <linux/if_ether.h>
  12 #include <net/netlink.h>
  13 
  14 #include <linux/netfilter.h>
  15 #include <linux/netfilter/ipset/ip_set.h>
  16 #include <linux/netfilter/ipset/ip_set_hash.h>
  17 
  18 #define IPSET_TYPE_REV_MIN      0
  19 #define IPSET_TYPE_REV_MAX      0
  20 
  21 MODULE_LICENSE("GPL");
  22 MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@netfilter.org>");
  23 IP_SET_MODULE_DESC("hash:mac", IPSET_TYPE_REV_MIN, IPSET_TYPE_REV_MAX);
  24 MODULE_ALIAS("ip_set_hash:mac");
  25 
  26 /* Type specific function prefix */
  27 #define HTYPE           hash_mac
  28 
  29 /* Member elements */
  30 struct hash_mac4_elem {
  31         /* Zero valued IP addresses cannot be stored */
  32         union {
  33                 unsigned char ether[ETH_ALEN];
  34                 __be32 foo[2];
  35         };
  36 };
  37 
  38 /* Common functions */
  39 
  40 static inline bool
  41 hash_mac4_data_equal(const struct hash_mac4_elem *e1,
  42                      const struct hash_mac4_elem *e2,
  43                      u32 *multi)
  44 {
  45         return ether_addr_equal(e1->ether, e2->ether);
  46 }
  47 
  48 static inline bool
  49 hash_mac4_data_list(struct sk_buff *skb, const struct hash_mac4_elem *e)
  50 {
  51         if (nla_put(skb, IPSET_ATTR_ETHER, ETH_ALEN, e->ether))
  52                 goto nla_put_failure;
  53         return false;
  54 
  55 nla_put_failure:
  56         return true;
  57 }
  58 
  59 static inline void
  60 hash_mac4_data_next(struct hash_mac4_elem *next,
  61                     const struct hash_mac4_elem *e)
  62 {
  63 }
  64 
  65 #define MTYPE           hash_mac4
  66 #define HOST_MASK       32
  67 #define IP_SET_EMIT_CREATE
  68 #define IP_SET_PROTO_UNDEF
  69 #include "ip_set_hash_gen.h"
  70 
  71 static int
  72 hash_mac4_kadt(struct ip_set *set, const struct sk_buff *skb,
  73                const struct xt_action_param *par,
  74                enum ipset_adt adt, struct ip_set_adt_opt *opt)
  75 {
  76         ipset_adtfn adtfn = set->variant->adt[adt];
  77         struct hash_mac4_elem e = { { .foo[0] = 0, .foo[1] = 0 } };
  78         struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
  79 
  80         if (skb_mac_header(skb) < skb->head ||
  81             (skb_mac_header(skb) + ETH_HLEN) > skb->data)
  82                 return -EINVAL;
  83 
  84         if (opt->flags & IPSET_DIM_ONE_SRC)
  85                 ether_addr_copy(e.ether, eth_hdr(skb)->h_source);
  86         else
  87                 ether_addr_copy(e.ether, eth_hdr(skb)->h_dest);
  88 
  89         if (is_zero_ether_addr(e.ether))
  90                 return -EINVAL;
  91         return adtfn(set, &e, &ext, &opt->ext, opt->cmdflags);
  92 }
  93 
  94 static int
  95 hash_mac4_uadt(struct ip_set *set, struct nlattr *tb[],
  96                enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
  97 {
  98         ipset_adtfn adtfn = set->variant->adt[adt];
  99         struct hash_mac4_elem e = { { .foo[0] = 0, .foo[1] = 0 } };
 100         struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
 101         int ret;
 102 
 103         if (tb[IPSET_ATTR_LINENO])
 104                 *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
 105 
 106         if (unlikely(!tb[IPSET_ATTR_ETHER] ||
 107                      nla_len(tb[IPSET_ATTR_ETHER]) != ETH_ALEN))
 108                 return -IPSET_ERR_PROTOCOL;
 109 
 110         ret = ip_set_get_extensions(set, tb, &ext);
 111         if (ret)
 112                 return ret;
 113         ether_addr_copy(e.ether, nla_data(tb[IPSET_ATTR_ETHER]));
 114         if (is_zero_ether_addr(e.ether))
 115                 return -IPSET_ERR_HASH_ELEM;
 116 
 117         return adtfn(set, &e, &ext, &ext, flags);
 118 }
 119 
 120 static struct ip_set_type hash_mac_type __read_mostly = {
 121         .name           = "hash:mac",
 122         .protocol       = IPSET_PROTOCOL,
 123         .features       = IPSET_TYPE_MAC,
 124         .dimension      = IPSET_DIM_ONE,
 125         .family         = NFPROTO_UNSPEC,
 126         .revision_min   = IPSET_TYPE_REV_MIN,
 127         .revision_max   = IPSET_TYPE_REV_MAX,
 128         .create         = hash_mac_create,
 129         .create_policy  = {
 130                 [IPSET_ATTR_HASHSIZE]   = { .type = NLA_U32 },
 131                 [IPSET_ATTR_MAXELEM]    = { .type = NLA_U32 },
 132                 [IPSET_ATTR_PROBES]     = { .type = NLA_U8 },
 133                 [IPSET_ATTR_RESIZE]     = { .type = NLA_U8  },
 134                 [IPSET_ATTR_TIMEOUT]    = { .type = NLA_U32 },
 135                 [IPSET_ATTR_CADT_FLAGS] = { .type = NLA_U32 },
 136         },
 137         .adt_policy     = {
 138                 [IPSET_ATTR_ETHER]      = { .type = NLA_BINARY,
 139                                             .len  = ETH_ALEN },
 140                 [IPSET_ATTR_TIMEOUT]    = { .type = NLA_U32 },
 141                 [IPSET_ATTR_LINENO]     = { .type = NLA_U32 },
 142                 [IPSET_ATTR_BYTES]      = { .type = NLA_U64 },
 143                 [IPSET_ATTR_PACKETS]    = { .type = NLA_U64 },
 144                 [IPSET_ATTR_COMMENT]    = { .type = NLA_NUL_STRING,
 145                                             .len  = IPSET_MAX_COMMENT_SIZE },
 146                 [IPSET_ATTR_SKBMARK]    = { .type = NLA_U64 },
 147                 [IPSET_ATTR_SKBPRIO]    = { .type = NLA_U32 },
 148                 [IPSET_ATTR_SKBQUEUE]   = { .type = NLA_U16 },
 149         },
 150         .me             = THIS_MODULE,
 151 };
 152 
 153 static int __init
 154 hash_mac_init(void)
 155 {
 156         return ip_set_type_register(&hash_mac_type);
 157 }
 158 
 159 static void __exit
 160 hash_mac_fini(void)
 161 {
 162         rcu_barrier();
 163         ip_set_type_unregister(&hash_mac_type);
 164 }
 165 
 166 module_init(hash_mac_init);
 167 module_exit(hash_mac_fini);

/* [<][>][^][v][top][bottom][index][help] */