1 /* Shared library add-on to iptables to add bridge port matching support. */
8 #include <linux/netfilter_ipv6/ip6t_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 ip6t_entry_match
*m
, unsigned int *nfcache
)
43 parse(int c
, char **argv
, int invert
, unsigned int *flags
,
44 const struct ip6t_entry
*entry
,
45 unsigned int *nfcache
,
46 struct ip6t_entry_match
**match
)
48 struct ip6t_physdev_info
*info
=
49 (struct ip6t_physdev_info
*)(*match
)->data
;
53 if (*flags
& IP6T_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
|= IP6T_PHYSDEV_OP_IN
;
60 info
->bitmask
|= IP6T_PHYSDEV_OP_IN
;
61 *flags
|= IP6T_PHYSDEV_OP_IN
;
65 if (*flags
& IP6T_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
|= IP6T_PHYSDEV_OP_OUT
;
72 info
->bitmask
|= IP6T_PHYSDEV_OP_OUT
;
73 *flags
|= IP6T_PHYSDEV_OP_OUT
;
77 if (*flags
& IP6T_PHYSDEV_OP_ISIN
)
79 check_inverse(optarg
, &invert
, &optind
, 0);
80 info
->bitmask
|= IP6T_PHYSDEV_OP_ISIN
;
82 info
->invert
|= IP6T_PHYSDEV_OP_ISIN
;
83 *flags
|= IP6T_PHYSDEV_OP_ISIN
;
87 if (*flags
& IP6T_PHYSDEV_OP_ISOUT
)
89 check_inverse(optarg
, &invert
, &optind
, 0);
90 info
->bitmask
|= IP6T_PHYSDEV_OP_ISOUT
;
92 info
->invert
|= IP6T_PHYSDEV_OP_ISOUT
;
93 *flags
|= IP6T_PHYSDEV_OP_ISOUT
;
97 if (*flags
& IP6T_PHYSDEV_OP_BRIDGED
)
99 check_inverse(optarg
, &invert
, &optind
, 0);
101 info
->invert
|= IP6T_PHYSDEV_OP_BRIDGED
;
102 *flags
|= IP6T_PHYSDEV_OP_BRIDGED
;
103 info
->bitmask
|= IP6T_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 ip6t_ip6
*ip
,
125 const struct ip6t_entry_match
*match
,
128 struct ip6t_physdev_info
*info
=
129 (struct ip6t_physdev_info
*)match
->data
;
131 printf("PHYSDEV match");
132 if (info
->bitmask
& IP6T_PHYSDEV_OP_ISIN
)
133 printf("%s --physdev-is-in",
134 info
->invert
& IP6T_PHYSDEV_OP_ISIN
? " !":"");
135 if (info
->bitmask
& IP6T_PHYSDEV_OP_IN
)
136 printf("%s --physdev-in %s",
137 (info
->invert
& IP6T_PHYSDEV_OP_IN
) ? " !":"", info
->physindev
);
139 if (info
->bitmask
& IP6T_PHYSDEV_OP_ISOUT
)
140 printf("%s --physdev-is-out",
141 info
->invert
& IP6T_PHYSDEV_OP_ISOUT
? " !":"");
142 if (info
->bitmask
& IP6T_PHYSDEV_OP_OUT
)
143 printf("%s --physdev-out %s",
144 (info
->invert
& IP6T_PHYSDEV_OP_OUT
) ? " !":"", info
->physoutdev
);
145 if (info
->bitmask
& IP6T_PHYSDEV_OP_BRIDGED
)
146 printf("%s --physdev-is-bridged",
147 info
->invert
& IP6T_PHYSDEV_OP_BRIDGED
? " !":"");
151 static void save(const struct ip6t_ip6
*ip
, const struct ip6t_entry_match
*match
)
153 struct ip6t_physdev_info
*info
=
154 (struct ip6t_physdev_info
*)match
->data
;
156 if (info
->bitmask
& IP6T_PHYSDEV_OP_ISIN
)
157 printf("%s --physdev-is-in",
158 info
->invert
& IP6T_PHYSDEV_OP_ISIN
? " !":"");
159 if (info
->bitmask
& IP6T_PHYSDEV_OP_IN
)
160 printf("%s --physdev-in %s",
161 (info
->invert
& IP6T_PHYSDEV_OP_IN
) ? " !":"", info
->physindev
);
163 if (info
->bitmask
& IP6T_PHYSDEV_OP_ISOUT
)
164 printf("%s --physdev-is-out",
165 info
->invert
& IP6T_PHYSDEV_OP_ISOUT
? " !":"");
166 if (info
->bitmask
& IP6T_PHYSDEV_OP_OUT
)
167 printf("%s --physdev-out %s",
168 (info
->invert
& IP6T_PHYSDEV_OP_OUT
) ? " !":"", info
->physoutdev
);
169 if (info
->bitmask
& IP6T_PHYSDEV_OP_BRIDGED
)
170 printf("%s --physdev-is-bridged",
171 info
->invert
& IP6T_PHYSDEV_OP_BRIDGED
? " !":"");
175 static struct ip6tables_match physdev
= {
177 .version
= IPTABLES_VERSION
,
178 .size
= IP6T_ALIGN(sizeof(struct ip6t_physdev_info
)),
179 .userspacesize
= IP6T_ALIGN(sizeof(struct ip6t_physdev_info
)),
183 .final_check
= &final_check
,
191 register_match6(&physdev
);