Summary
Looks like Flower.encode() uses EncSrcIPMask when encoding EncDestIP, instead of EncDestIPMask. As a result, encapsulated destination IP filters may be encoded with the wrong mask when source and destination masks differ.
Details
- Affected: v1.3.1 and current master
- In filter_linux.go, encode() does:
if filter.EncDestIP != nil {
filter.encodeIP(parent, filter.EncDestIP, filter.EncSrcIPMask,
nl.TCA_FLOWER_KEY_ENC_IPV4_DST, nl.TCA_FLOWER_KEY_ENC_IPV6_DST,
nl.TCA_FLOWER_KEY_ENC_IPV4_DST_MASK, nl.TCA_FLOWER_KEY_ENC_IPV6_DST_MASK)
}
But Flower defines a separate EncDestIPMask field, and decode() correctly reads destination encapsulated mask into EncDestIPMask.
srcMask := net.IPv4Mask(255, 255, 255, 0)
dstMask := net.IPv4Mask(255, 255, 0, 0)
filter := &netlink.Flower{
FilterAttrs: netlink.FilterAttrs{
LinkIndex: link.Attrs().Index,
Parent: netlink.HANDLE_INGRESS,
Priority: 10,
Protocol: unix.ETH_P_IP,
},
EncSrcIP: net.ParseIP("10.10.10.1").To4(),
EncSrcIPMask: srcMask,
EncDestIP: net.ParseIP("20.20.20.1").To4(),
EncDestIPMask: dstMask,
}
netlink.FilterList and maskString returning the same mask with /24 of 32
Fix
if filter.EncDestIP != nil {
- filter.encodeIP(parent, filter.EncDestIP, filter.EncSrcIPMask,
+ filter.encodeIP(parent, filter.EncDestIP, filter.EncDestIPMask,
nl.TCA_FLOWER_KEY_ENC_IPV4_DST, nl.TCA_FLOWER_KEY_ENC_IPV6_DST,
nl.TCA_FLOWER_KEY_ENC_IPV4_DST_MASK, nl.TCA_FLOWER_KEY_ENC_IPV6_DST_MASK)
}
Summary
Looks like Flower.encode() uses EncSrcIPMask when encoding EncDestIP, instead of EncDestIPMask. As a result, encapsulated destination IP filters may be encoded with the wrong mask when source and destination masks differ.
Details
But Flower defines a separate EncDestIPMask field, and decode() correctly reads destination encapsulated mask into EncDestIPMask.
netlink.FilterList and maskString returning the same mask with /24 of 32
Fix