diff mbox

[ovs-dev,v4,5/7] dpif-netlink: Don't send PACKET_TYPE to kernel

Message ID AM2PR07MB10421D1B3D34E1D6D99FEE688A1E0@AM2PR07MB1042.eurprd07.prod.outlook.com
State Superseded
Headers show

Commit Message

Zoltan Balogh April 25, 2017, 4:30 p.m. UTC
The kernel datapath does not support the packet_type match field.
Instead it encodes the packet type implictly by the presence or absence of
the Ethernet attribute in the flow key and mask.

This patch filters the PACKET_TYPE attribute out of netlink flow key and
mask to be sent to the kernel datapath.

Signed-off-by: Zoltan Balogh <zoltan.balogh@ericsson.com>
---
 lib/dpif-netlink.c | 37 ++++++++++++++++++++++++++++++++-----
 1 file changed, 32 insertions(+), 5 deletions(-)
diff mbox

Patch

diff --git a/lib/dpif-netlink.c b/lib/dpif-netlink.c
index d80f6d8..0704e0b 100644
--- a/lib/dpif-netlink.c
+++ b/lib/dpif-netlink.c
@@ -2916,6 +2916,34 @@  dpif_netlink_flow_from_ofpbuf(struct dpif_netlink_flow *flow,
     return 0;
 }
 
+static inline void
+nl_msg_put_exclude_packet_type(struct ofpbuf* buf, uint16_t type,
+                               const struct nlattr *data,
+                               uint16_t data_len)
+{
+    const struct nlattr *packet_type = nl_attr_find__(data, data_len,
+                                                      OVS_KEY_ATTR_PACKET_TYPE);
+    if (packet_type) {
+        /* exclude PACKET_TYPE Netlink attribute. */
+        ovs_assert(NLA_ALIGN(packet_type->nla_len) == NLA_HDRLEN + sizeof(uint32_t));
+
+        size_t packet_type_len = NLA_HDRLEN + sizeof(uint32_t);
+        size_t first_chunk_size =
+                (size_t)((uint8_t *)packet_type - (uint8_t *)data);
+        size_t second_chunk_size = data_len - first_chunk_size
+                                   - packet_type_len;
+        uint8_t *first_attr = NULL;
+        struct nlattr *next_attr = nl_attr_next(packet_type);
+
+        first_attr = nl_msg_put_unspec_uninit(buf, type,
+                                              data_len - packet_type_len);
+        memcpy(first_attr, data, first_chunk_size);
+        memcpy(first_attr + first_chunk_size, next_attr, second_chunk_size);
+    } else {
+        nl_msg_put_unspec(buf, type, data, data_len);
+    }
+}
+
 /* Appends to 'buf' (which must initially be empty) a "struct ovs_header"
  * followed by Netlink attributes corresponding to 'flow'. */
 static void
@@ -2942,13 +2970,12 @@  dpif_netlink_flow_to_ofpbuf(const struct dpif_netlink_flow *flow,
     }
     if (!flow->ufid_terse || !flow->ufid_present) {
         if (flow->key_len) {
-            nl_msg_put_unspec(buf, OVS_FLOW_ATTR_KEY,
-                              flow->key, flow->key_len);
+            nl_msg_put_exclude_packet_type(buf, OVS_FLOW_ATTR_KEY, flow->key,
+                                           flow->key_len);
         }
-
         if (flow->mask_len) {
-            nl_msg_put_unspec(buf, OVS_FLOW_ATTR_MASK,
-                              flow->mask, flow->mask_len);
+            nl_msg_put_exclude_packet_type(buf, OVS_FLOW_ATTR_MASK, flow->mask,
+                                           flow->mask_len);
         }
         if (flow->actions || flow->actions_len) {
             nl_msg_put_unspec(buf, OVS_FLOW_ATTR_ACTIONS,