1 /* Shared library add-on to iptables to add bridge port matching support. */
8 #include <linux/netfilter_ipv4/ipt_physdev.h>
9 #if defined(__GLIBC__) && __GLIBC__ == 2
10 #include <net/ethernet.h>
12 #include <linux/if_ether.h>
19 "physdev v%s options:\n"
20 " --physdev-in [!] input name[+] bridge port name ([+] for wildcard)\n"
21 " --physdev-out [!] output name[+] bridge port name ([+] for wildcard)\n"
22 " [!] --physdev-is-in arrived on a bridge device\n"
23 " [!] --physdev-is-out will leave on a bridge device\n"
24 " [!] --physdev-is-bridged it's a bridged packet\n"
25 "\n", IPTABLES_VERSION);
28 static struct option opts[] = {
29 { "physdev-in", 1, 0, '1' },
30 { "physdev-out", 1, 0, '2' },
31 { "physdev-is-in", 0, 0, '3' },
32 { "physdev-is-out", 0, 0, '4' },
33 { "physdev-is-bridged", 0, 0, '5' },
38 init(struct ipt_entry_match *m, unsigned int *nfcache)
43 parse(int c, char **argv, int invert, unsigned int *flags,
44 const struct ipt_entry *entry,
45 unsigned int *nfcache,
46 struct ipt_entry_match **match)
48 struct ipt_physdev_info *info =
49 (struct ipt_physdev_info*)(*match)->data;
53 if (*flags & IPT_PHYSDEV_OP_IN)
55 check_inverse(optarg, &invert, &optind, 0);
56 parse_interface(argv[optind-1], info->physindev,
57 (unsigned char *)info->in_mask);
59 info->invert |= IPT_PHYSDEV_OP_IN;
60 info->bitmask |= IPT_PHYSDEV_OP_IN;
61 *flags |= IPT_PHYSDEV_OP_IN;
65 if (*flags & IPT_PHYSDEV_OP_OUT)
67 check_inverse(optarg, &invert, &optind, 0);
68 parse_interface(argv[optind-1], info->physoutdev,
69 (unsigned char *)info->out_mask);
71 info->invert |= IPT_PHYSDEV_OP_OUT;
72 info->bitmask |= IPT_PHYSDEV_OP_OUT;
73 *flags |= IPT_PHYSDEV_OP_OUT;
77 if (*flags & IPT_PHYSDEV_OP_ISIN)
79 check_inverse(optarg, &invert, &optind, 0);
80 info->bitmask |= IPT_PHYSDEV_OP_ISIN;
82 info->invert |= IPT_PHYSDEV_OP_ISIN;
83 *flags |= IPT_PHYSDEV_OP_ISIN;
87 if (*flags & IPT_PHYSDEV_OP_ISOUT)
89 check_inverse(optarg, &invert, &optind, 0);
90 info->bitmask |= IPT_PHYSDEV_OP_ISOUT;
92 info->invert |= IPT_PHYSDEV_OP_ISOUT;
93 *flags |= IPT_PHYSDEV_OP_ISOUT;
97 if (*flags & IPT_PHYSDEV_OP_BRIDGED)
99 check_inverse(optarg, &invert, &optind, 0);
101 info->invert |= IPT_PHYSDEV_OP_BRIDGED;
102 *flags |= IPT_PHYSDEV_OP_BRIDGED;
103 info->bitmask |= IPT_PHYSDEV_OP_BRIDGED;
112 exit_error(PARAMETER_PROBLEM,
113 "multiple use of the same physdev option is not allowed");
117 static void final_check(unsigned int flags)
120 exit_error(PARAMETER_PROBLEM, "PHYSDEV: no physdev option specified");
124 print(const struct ipt_ip *ip,
125 const struct ipt_entry_match *match,
128 struct ipt_physdev_info *info =
129 (struct ipt_physdev_info*)match->data;
131 printf("PHYSDEV match");
132 if (info->bitmask & IPT_PHYSDEV_OP_ISIN)
133 printf("%s --physdev-is-in",
134 info->invert & IPT_PHYSDEV_OP_ISIN ? " !":"");
135 if (info->bitmask & IPT_PHYSDEV_OP_IN)
136 printf("%s --physdev-in %s",
137 (info->invert & IPT_PHYSDEV_OP_IN) ? " !":"", info->physindev);
139 if (info->bitmask & IPT_PHYSDEV_OP_ISOUT)
140 printf("%s --physdev-is-out",
141 info->invert & IPT_PHYSDEV_OP_ISOUT ? " !":"");
142 if (info->bitmask & IPT_PHYSDEV_OP_OUT)
143 printf("%s --physdev-out %s",
144 (info->invert & IPT_PHYSDEV_OP_OUT) ? " !":"", info->physoutdev);
145 if (info->bitmask & IPT_PHYSDEV_OP_BRIDGED)
146 printf("%s --physdev-is-bridged",
147 info->invert & IPT_PHYSDEV_OP_BRIDGED ? " !":"");
151 static void save(const struct ipt_ip *ip, const struct ipt_entry_match *match)
153 struct ipt_physdev_info *info =
154 (struct ipt_physdev_info*)match->data;
156 if (info->bitmask & IPT_PHYSDEV_OP_ISIN)
157 printf("%s --physdev-is-in",
158 info->invert & IPT_PHYSDEV_OP_ISIN ? " !":"");
159 if (info->bitmask & IPT_PHYSDEV_OP_IN)
160 printf("%s --physdev-in %s",
161 (info->invert & IPT_PHYSDEV_OP_IN) ? " !":"", info->physindev);
163 if (info->bitmask & IPT_PHYSDEV_OP_ISOUT)
164 printf("%s --physdev-is-out",
165 info->invert & IPT_PHYSDEV_OP_ISOUT ? " !":"");
166 if (info->bitmask & IPT_PHYSDEV_OP_OUT)
167 printf("%s --physdev-out %s",
168 (info->invert & IPT_PHYSDEV_OP_OUT) ? " !":"", info->physoutdev);
169 if (info->bitmask & IPT_PHYSDEV_OP_BRIDGED)
170 printf("%s --physdev-is-bridged",
171 info->invert & IPT_PHYSDEV_OP_BRIDGED ? " !":"");
175 static struct iptables_match physdev = {
178 .version = IPTABLES_VERSION,
179 .size = IPT_ALIGN(sizeof(struct ipt_physdev_info)),
180 .userspacesize = IPT_ALIGN(sizeof(struct ipt_physdev_info)),
184 .final_check = &final_check,
192 register_match(&physdev);