summaryrefslogtreecommitdiffstats
path: root/net/openvswitch/conntrack.c
diff options
context:
space:
mode:
authorJarno Rajahalme <jarno@ovn.org>2017-04-21 19:48:06 -0400
committerDavid S. Miller <davem@davemloft.net>2017-04-24 13:53:25 -0400
commit120645513f55a4ac5543120d9e79925d30a0156f (patch)
tree5a079ff418ef0a96bdd11558f90295d3461bd465 /net/openvswitch/conntrack.c
parentabd0a4f2b41812e9ba334945e256909e3d28da57 (diff)
openvswitch: Add eventmask support to CT action.
Add a new optional conntrack action attribute OVS_CT_ATTR_EVENTMASK, which can be used in conjunction with the commit flag (OVS_CT_ATTR_COMMIT) to set the mask of bits specifying which conntrack events (IPCT_*) should be delivered via the Netfilter netlink multicast groups. Default behavior depends on the system configuration, but typically a lot of events are delivered. This can be very chatty for the NFNLGRP_CONNTRACK_UPDATE group, even if only some types of events are of interest. Netfilter core init_conntrack() adds the event cache extension, so we only need to set the ctmask value. However, if the system is configured without support for events, the setting will be skipped due to extension not being found. Signed-off-by: Jarno Rajahalme <jarno@ovn.org> Reviewed-by: Greg Rose <gvrose8192@gmail.com> Acked-by: Joe Stringer <joe@ovn.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/openvswitch/conntrack.c')
-rw-r--r--net/openvswitch/conntrack.c27
1 files changed, 27 insertions, 0 deletions
diff --git a/net/openvswitch/conntrack.c b/net/openvswitch/conntrack.c
index 58de4c2da673..4f7c3b5c080b 100644
--- a/net/openvswitch/conntrack.c
+++ b/net/openvswitch/conntrack.c
@@ -66,7 +66,9 @@ struct ovs_conntrack_info {
66 u8 commit : 1; 66 u8 commit : 1;
67 u8 nat : 3; /* enum ovs_ct_nat */ 67 u8 nat : 3; /* enum ovs_ct_nat */
68 u8 force : 1; 68 u8 force : 1;
69 u8 have_eventmask : 1;
69 u16 family; 70 u16 family;
71 u32 eventmask; /* Mask of 1 << IPCT_*. */
70 struct md_mark mark; 72 struct md_mark mark;
71 struct md_labels labels; 73 struct md_labels labels;
72#ifdef CONFIG_NF_NAT_NEEDED 74#ifdef CONFIG_NF_NAT_NEEDED
@@ -1007,6 +1009,20 @@ static int ovs_ct_commit(struct net *net, struct sw_flow_key *key,
1007 if (!ct) 1009 if (!ct)
1008 return 0; 1010 return 0;
1009 1011
1012 /* Set the conntrack event mask if given. NEW and DELETE events have
1013 * their own groups, but the NFNLGRP_CONNTRACK_UPDATE group listener
1014 * typically would receive many kinds of updates. Setting the event
1015 * mask allows those events to be filtered. The set event mask will
1016 * remain in effect for the lifetime of the connection unless changed
1017 * by a further CT action with both the commit flag and the eventmask
1018 * option. */
1019 if (info->have_eventmask) {
1020 struct nf_conntrack_ecache *cache = nf_ct_ecache_find(ct);
1021
1022 if (cache)
1023 cache->ctmask = info->eventmask;
1024 }
1025
1010 /* Apply changes before confirming the connection so that the initial 1026 /* Apply changes before confirming the connection so that the initial
1011 * conntrack NEW netlink event carries the values given in the CT 1027 * conntrack NEW netlink event carries the values given in the CT
1012 * action. 1028 * action.
@@ -1238,6 +1254,8 @@ static const struct ovs_ct_len_tbl ovs_ct_attr_lens[OVS_CT_ATTR_MAX + 1] = {
1238 /* NAT length is checked when parsing the nested attributes. */ 1254 /* NAT length is checked when parsing the nested attributes. */
1239 [OVS_CT_ATTR_NAT] = { .minlen = 0, .maxlen = INT_MAX }, 1255 [OVS_CT_ATTR_NAT] = { .minlen = 0, .maxlen = INT_MAX },
1240#endif 1256#endif
1257 [OVS_CT_ATTR_EVENTMASK] = { .minlen = sizeof(u32),
1258 .maxlen = sizeof(u32) },
1241}; 1259};
1242 1260
1243static int parse_ct(const struct nlattr *attr, struct ovs_conntrack_info *info, 1261static int parse_ct(const struct nlattr *attr, struct ovs_conntrack_info *info,
@@ -1316,6 +1334,11 @@ static int parse_ct(const struct nlattr *attr, struct ovs_conntrack_info *info,
1316 break; 1334 break;
1317 } 1335 }
1318#endif 1336#endif
1337 case OVS_CT_ATTR_EVENTMASK:
1338 info->have_eventmask = true;
1339 info->eventmask = nla_get_u32(a);
1340 break;
1341
1319 default: 1342 default:
1320 OVS_NLERR(log, "Unknown conntrack attr (%d)", 1343 OVS_NLERR(log, "Unknown conntrack attr (%d)",
1321 type); 1344 type);
@@ -1515,6 +1538,10 @@ int ovs_ct_action_to_attr(const struct ovs_conntrack_info *ct_info,
1515 ct_info->helper->name)) 1538 ct_info->helper->name))
1516 return -EMSGSIZE; 1539 return -EMSGSIZE;
1517 } 1540 }
1541 if (ct_info->have_eventmask &&
1542 nla_put_u32(skb, OVS_CT_ATTR_EVENTMASK, ct_info->eventmask))
1543 return -EMSGSIZE;
1544
1518#ifdef CONFIG_NF_NAT_NEEDED 1545#ifdef CONFIG_NF_NAT_NEEDED
1519 if (ct_info->nat && !ovs_ct_nat_to_attr(ct_info, skb)) 1546 if (ct_info->nat && !ovs_ct_nat_to_attr(ct_info, skb))
1520 return -EMSGSIZE; 1547 return -EMSGSIZE;