-o foobar;=;FAIL
--logical-in br0;=;OK
--logical-out br1;=;FAIL
+-i + -d 00:0f:ee:d0:ba:be;-d 00:0f:ee:d0:ba:be;OK
+-i + -p ip;-p IPv4;OK
+--logical-in + -d 00:0f:ee:d0:ba:be;-d 00:0f:ee:d0:ba:be;OK
+--logical-in + -p ip;-p IPv4;OK
:FORWARD
-i foobar;=;OK
-o foobar;=;OK
! -d ::;! -d ::/128;OK
! -s ::;! -s ::/128;OK
-s ::/64;=;OK
+:INPUT
+-i + -d c0::fe;-d c0::fe/128;OK
+-i + -p tcp;-p tcp;OK
:FORWARD
--protocol=tcp --source=1.2.3.4 --destination=5.6.7.8/32 --in-interface=eth0 --out-interface=eth1 --jump=ACCEPT;-s 1.2.3.4/32 -d 5.6.7.8/32 -i eth0 -o eth1 -p tcp -j ACCEPT;OK
-ptcp -s1.2.3.4 -d5.6.7.8/32 -ieth0 -oeth1 -jACCEPT;-s 1.2.3.4/32 -d 5.6.7.8/32 -i eth0 -o eth1 -p tcp -j ACCEPT;OK
+-i + -d 1.2.3.4;-d 1.2.3.4/32;OK
+-i + -p tcp;-p tcp;OK
if (fw->arp.iniface[0] != '\0') {
op = nft_invflags2cmp(fw->arp.invflags, IPT_INV_VIA_IN);
- add_iniface(h, r, fw->arp.iniface, op);
+ add_iface(h, r, fw->arp.iniface, NFT_META_IIFNAME, op);
}
if (fw->arp.outiface[0] != '\0') {
op = nft_invflags2cmp(fw->arp.invflags, IPT_INV_VIA_OUT);
- add_outiface(h, r, fw->arp.outiface, op);
+ add_iface(h, r, fw->arp.outiface, NFT_META_OIFNAME, op);
}
if (fw->arp.arhrd != 0 ||
xtables_print_mac_and_mask(mac, mask);
}
-static void add_logical_iniface(struct nft_handle *h, struct nftnl_rule *r,
- char *iface, uint32_t op)
-{
- int iface_len;
- uint8_t reg;
-
- iface_len = strlen(iface);
-
- add_meta(h, r, NFT_META_BRI_IIFNAME, ®);
- if (iface[iface_len - 1] == '+')
- add_cmp_ptr(r, op, iface, iface_len - 1, reg);
- else
- add_cmp_ptr(r, op, iface, iface_len + 1, reg);
-}
-
-static void add_logical_outiface(struct nft_handle *h, struct nftnl_rule *r,
- char *iface, uint32_t op)
-{
- int iface_len;
- uint8_t reg;
-
- iface_len = strlen(iface);
-
- add_meta(h, r, NFT_META_BRI_OIFNAME, ®);
- if (iface[iface_len - 1] == '+')
- add_cmp_ptr(r, op, iface, iface_len - 1, reg);
- else
- add_cmp_ptr(r, op, iface, iface_len + 1, reg);
-}
-
static int add_meta_broute(struct nftnl_rule *r)
{
struct nftnl_expr *expr;
if (fw->in[0] != '\0') {
op = nft_invflags2cmp(fw->invflags, EBT_IIN);
- add_iniface(h, r, fw->in, op);
+ add_iface(h, r, fw->in, NFT_META_IIFNAME, op);
}
if (fw->out[0] != '\0') {
op = nft_invflags2cmp(fw->invflags, EBT_IOUT);
- add_outiface(h, r, fw->out, op);
+ add_iface(h, r, fw->out, NFT_META_OIFNAME, op);
}
if (fw->logical_in[0] != '\0') {
op = nft_invflags2cmp(fw->invflags, EBT_ILOGICALIN);
- add_logical_iniface(h, r, fw->logical_in, op);
+ add_iface(h, r, fw->logical_in, NFT_META_BRI_IIFNAME, op);
}
if (fw->logical_out[0] != '\0') {
op = nft_invflags2cmp(fw->invflags, EBT_ILOGICALOUT);
- add_logical_outiface(h, r, fw->logical_out, op);
+ add_iface(h, r, fw->logical_out, NFT_META_BRI_OIFNAME, op);
}
if ((fw->bitmask & EBT_NOPROTO) == 0) {
if (cs->fw.ip.iniface[0] != '\0') {
op = nft_invflags2cmp(cs->fw.ip.invflags, IPT_INV_VIA_IN);
- add_iniface(h, r, cs->fw.ip.iniface, op);
+ add_iface(h, r, cs->fw.ip.iniface, NFT_META_IIFNAME, op);
}
if (cs->fw.ip.outiface[0] != '\0') {
op = nft_invflags2cmp(cs->fw.ip.invflags, IPT_INV_VIA_OUT);
- add_outiface(h, r, cs->fw.ip.outiface, op);
+ add_iface(h, r, cs->fw.ip.outiface, NFT_META_OIFNAME, op);
}
if (cs->fw.ip.proto != 0) {
if (cs->fw6.ipv6.iniface[0] != '\0') {
op = nft_invflags2cmp(cs->fw6.ipv6.invflags, IPT_INV_VIA_IN);
- add_iniface(h, r, cs->fw6.ipv6.iniface, op);
+ add_iface(h, r, cs->fw6.ipv6.iniface, NFT_META_IIFNAME, op);
}
if (cs->fw6.ipv6.outiface[0] != '\0') {
op = nft_invflags2cmp(cs->fw6.ipv6.invflags, IPT_INV_VIA_OUT);
- add_outiface(h, r, cs->fw6.ipv6.outiface, op);
+ add_iface(h, r, cs->fw6.ipv6.outiface, NFT_META_OIFNAME, op);
}
if (cs->fw6.ipv6.proto != 0) {
add_cmp_ptr(r, op, &val, sizeof(val), sreg);
}
-void add_iniface(struct nft_handle *h, struct nftnl_rule *r,
- char *iface, uint32_t op)
+void add_iface(struct nft_handle *h, struct nftnl_rule *r,
+ char *iface, uint32_t key, uint32_t op)
{
- int iface_len;
+ int iface_len = strlen(iface);
uint8_t reg;
- iface_len = strlen(iface);
- add_meta(h, r, NFT_META_IIFNAME, ®);
if (iface[iface_len - 1] == '+') {
- if (iface_len > 1)
- add_cmp_ptr(r, op, iface, iface_len - 1, reg);
- else if (op != NFT_CMP_EQ)
- add_cmp_ptr(r, NFT_CMP_EQ, "INVAL/D",
- strlen("INVAL/D") + 1, reg);
+ if (iface_len > 1) {
+ iface_len -= 1;
+ } else if (op != NFT_CMP_EQ) {
+ op = NFT_CMP_EQ;
+ iface = "INVAL/D";
+ iface_len = strlen(iface) + 1;
+ } else {
+ return; /* -o + */
+ }
} else {
- add_cmp_ptr(r, op, iface, iface_len + 1, reg);
+ iface_len += 1;
}
-}
-
-void add_outiface(struct nft_handle *h, struct nftnl_rule *r,
- char *iface, uint32_t op)
-{
- int iface_len;
- uint8_t reg;
- iface_len = strlen(iface);
-
- add_meta(h, r, NFT_META_OIFNAME, ®);
- if (iface[iface_len - 1] == '+') {
- if (iface_len > 1)
- add_cmp_ptr(r, op, iface, iface_len - 1, reg);
- else if (op != NFT_CMP_EQ)
- add_cmp_ptr(r, NFT_CMP_EQ, "INVAL/D",
- strlen("INVAL/D") + 1, reg);
- } else {
- add_cmp_ptr(r, op, iface, iface_len + 1, reg);
- }
+ add_meta(h, r, key, ®);
+ add_cmp_ptr(r, op, iface, iface_len, reg);
}
void add_addr(struct nft_handle *h, struct nftnl_rule *r,
void add_cmp_u8(struct nftnl_rule *r, uint8_t val, uint32_t op, uint8_t sreg);
void add_cmp_u16(struct nftnl_rule *r, uint16_t val, uint32_t op, uint8_t sreg);
void add_cmp_u32(struct nftnl_rule *r, uint32_t val, uint32_t op, uint8_t sreg);
-void add_iniface(struct nft_handle *h, struct nftnl_rule *r, char *iface, uint32_t op);
-void add_outiface(struct nft_handle *h, struct nftnl_rule *r, char *iface, uint32_t op);
+void add_iface(struct nft_handle *h, struct nftnl_rule *r,
+ char *iface, uint32_t key, uint32_t op);
void add_addr(struct nft_handle *h, struct nftnl_rule *r, enum nft_payload_bases base, int offset,
void *data, void *mask, size_t len, uint32_t op);
void add_proto(struct nft_handle *h, struct nftnl_rule *r, int offset, size_t len,