Extend sFlow agent to report tunnel and MPLS structures
[cascardo/ovs.git] / lib / dpif-netlink.c
index de43d80..8884a9f 100644 (file)
@@ -768,6 +768,9 @@ get_vport_type(const struct dpif_netlink_vport *vport)
     case OVS_VPORT_TYPE_LISP:
         return "lisp";
 
+    case OVS_VPORT_TYPE_STT:
+        return "stt";
+
     case OVS_VPORT_TYPE_UNSPEC:
     case __OVS_VPORT_TYPE_MAX:
         break;
@@ -787,6 +790,8 @@ netdev_to_ovs_vport_type(const struct netdev *netdev)
         return OVS_VPORT_TYPE_NETDEV;
     } else if (!strcmp(type, "internal")) {
         return OVS_VPORT_TYPE_INTERNAL;
+    } else if (strstr(type, "stt")) {
+        return OVS_VPORT_TYPE_STT;
     } else if (!strcmp(type, "geneve")) {
         return OVS_VPORT_TYPE_GENEVE;
     } else if (strstr(type, "gre64")) {
@@ -849,12 +854,26 @@ dpif_netlink_port_add__(struct dpif_netlink *dpif, struct netdev *netdev,
     }
 
     tnl_cfg = netdev_get_tunnel_config(netdev);
-    if (tnl_cfg && tnl_cfg->dst_port != 0) {
+    if (tnl_cfg && (tnl_cfg->dst_port != 0 || tnl_cfg->exts)) {
         ofpbuf_use_stack(&options, options_stub, sizeof options_stub);
-        nl_msg_put_u16(&options, OVS_TUNNEL_ATTR_DST_PORT,
-                       ntohs(tnl_cfg->dst_port));
-        request.options = ofpbuf_data(&options);
-        request.options_len = ofpbuf_size(&options);
+        if (tnl_cfg->dst_port) {
+            nl_msg_put_u16(&options, OVS_TUNNEL_ATTR_DST_PORT,
+                           ntohs(tnl_cfg->dst_port));
+        }
+        if (tnl_cfg->exts) {
+            size_t ext_ofs;
+            int i;
+
+            ext_ofs = nl_msg_start_nested(&options, OVS_TUNNEL_ATTR_EXTENSION);
+            for (i = 0; i < 32; i++) {
+                if (tnl_cfg->exts & (1 << i)) {
+                    nl_msg_put_flag(&options, i);
+                }
+            }
+            nl_msg_end_nested(&options, ext_ofs);
+        }
+        request.options = options.data;
+        request.options_len = options.size;
     }
 
     request.port_no = *port_nop;
@@ -1321,8 +1340,8 @@ dpif_netlink_init_flow_del(struct dpif_netlink *dpif,
                            const struct dpif_flow_del *del,
                            struct dpif_netlink_flow *request)
 {
-    return dpif_netlink_init_flow_del__(dpif, del->key, del->key_len,
-                                        del->ufid, del->terse, request);
+    dpif_netlink_init_flow_del__(dpif, del->key, del->key_len,
+                                 del->ufid, del->terse, request);
 }
 
 struct dpif_netlink_flow_dump {
@@ -1429,9 +1448,9 @@ dpif_netlink_flow_to_dpif_flow(struct dpif *dpif, struct dpif_flow *dpif_flow,
     dpif_flow->actions = datapath_flow->actions;
     dpif_flow->actions_len = datapath_flow->actions_len;
     dpif_flow->ufid_present = datapath_flow->ufid_present;
+    dpif_flow->pmd_id = PMD_ID_NULL;
     if (datapath_flow->ufid_present) {
         dpif_flow->ufid = datapath_flow->ufid;
-    dpif_flow->pmd_id = PMD_ID_NULL;
     } else {
         ovs_assert(datapath_flow->key && datapath_flow->key_len);
         dpif_flow_hash(dpif, datapath_flow->key, datapath_flow->key_len,
@@ -1455,7 +1474,7 @@ dpif_netlink_flow_dump_next(struct dpif_flow_dump_thread *thread_,
 
     n_flows = 0;
     while (!n_flows
-           || (n_flows < max_flows && ofpbuf_size(&thread->nl_flows))) {
+           || (n_flows < max_flows && thread->nl_flows.size)) {
         struct dpif_netlink_flow datapath_flow;
         struct ofpbuf nl_flow;
         int error;
@@ -1510,7 +1529,7 @@ dpif_netlink_encode_execute(int dp_ifindex, const struct dpif_execute *d_exec,
     size_t key_ofs;
 
     ofpbuf_prealloc_tailroom(buf, (64
-                                   + ofpbuf_size(d_exec->packet)
+                                   + dp_packet_size(d_exec->packet)
                                    + ODP_KEY_METADATA_SIZE
                                    + d_exec->actions_len));
 
@@ -1521,11 +1540,11 @@ dpif_netlink_encode_execute(int dp_ifindex, const struct dpif_execute *d_exec,
     k_exec->dp_ifindex = dp_ifindex;
 
     nl_msg_put_unspec(buf, OVS_PACKET_ATTR_PACKET,
-                      ofpbuf_data(d_exec->packet),
-                      ofpbuf_size(d_exec->packet));
+                      dp_packet_data(d_exec->packet),
+                      dp_packet_size(d_exec->packet));
 
     key_ofs = nl_msg_start_nested(buf, OVS_PACKET_ATTR_KEY);
-    odp_key_from_pkt_metadata(buf, &d_exec->md);
+    odp_key_from_pkt_metadata(buf, &d_exec->packet->md);
     nl_msg_end_nested(buf, key_ofs);
 
     nl_msg_put_unspec(buf, OVS_PACKET_ATTR_ACTIONS,
@@ -1597,14 +1616,14 @@ dpif_netlink_operate__(struct dpif_netlink *dpif,
         case DPIF_OP_EXECUTE:
             /* Can't execute a packet that won't fit in a Netlink attribute. */
             if (OVS_UNLIKELY(nl_attr_oversized(
-                                 ofpbuf_size(op->u.execute.packet)))) {
+                                 dp_packet_size(op->u.execute.packet)))) {
                 /* Report an error immediately if this is the first operation.
                  * Otherwise the easiest thing to do is to postpone to the next
                  * call (when this will be the first operation). */
                 if (i == 0) {
                     VLOG_ERR_RL(&error_rl,
                                 "dropping oversized %"PRIu32"-byte packet",
-                                ofpbuf_size(op->u.execute.packet));
+                                dp_packet_size(op->u.execute.packet));
                     op->error = ENOBUFS;
                     return 1;
                 }
@@ -1950,6 +1969,7 @@ parse_odp_packet(const struct dpif_netlink *dpif, struct ofpbuf *buf,
         /* OVS_PACKET_CMD_ACTION only. */
         [OVS_PACKET_ATTR_USERDATA] = { .type = NL_A_UNSPEC, .optional = true },
         [OVS_PACKET_ATTR_EGRESS_TUN_KEY] = { .type = NL_A_NESTED, .optional = true },
+        [OVS_PACKET_ATTR_ACTIONS] = { .type = NL_A_NESTED, .optional = true },
     };
 
     struct ovs_header *ovs_header;
@@ -1959,7 +1979,7 @@ parse_odp_packet(const struct dpif_netlink *dpif, struct ofpbuf *buf,
     struct ofpbuf b;
     int type;
 
-    ofpbuf_use_const(&b, ofpbuf_data(buf), ofpbuf_size(buf));
+    ofpbuf_use_const(&b, buf->data, buf->size);
 
     nlmsg = ofpbuf_try_pull(&b, sizeof *nlmsg);
     genl = ofpbuf_try_pull(&b, sizeof *genl);
@@ -1986,16 +2006,17 @@ parse_odp_packet(const struct dpif_netlink *dpif, struct ofpbuf *buf,
     dpif_flow_hash(&dpif->dpif, upcall->key, upcall->key_len, &upcall->ufid);
     upcall->userdata = a[OVS_PACKET_ATTR_USERDATA];
     upcall->out_tun_key = a[OVS_PACKET_ATTR_EGRESS_TUN_KEY];
+    upcall->actions = a[OVS_PACKET_ATTR_ACTIONS];
 
     /* Allow overwriting the netlink attribute header without reallocating. */
-    ofpbuf_use_stub(&upcall->packet,
+    dp_packet_use_stub(&upcall->packet,
                     CONST_CAST(struct nlattr *,
                                nl_attr_get(a[OVS_PACKET_ATTR_PACKET])) - 1,
                     nl_attr_get_size(a[OVS_PACKET_ATTR_PACKET]) +
                     sizeof(struct nlattr));
-    ofpbuf_set_data(&upcall->packet,
-                    (char *)ofpbuf_data(&upcall->packet) + sizeof(struct nlattr));
-    ofpbuf_set_size(&upcall->packet, nl_attr_get_size(a[OVS_PACKET_ATTR_PACKET]));
+    dp_packet_set_data(&upcall->packet,
+                    (char *)dp_packet_data(&upcall->packet) + sizeof(struct nlattr));
+    dp_packet_set_size(&upcall->packet, nl_attr_get_size(a[OVS_PACKET_ATTR_PACKET]));
 
     *dp_ifindex = ovs_header->dp_ifindex;
 
@@ -2260,6 +2281,7 @@ dpif_netlink_get_datapath_version(void)
 
 const struct dpif_class dpif_netlink_class = {
     "system",
+    NULL,                       /* init */
     dpif_netlink_enumerate,
     NULL,
     dpif_netlink_open,
@@ -2379,7 +2401,7 @@ dpif_netlink_vport_from_ofpbuf(struct dpif_netlink_vport *vport,
 
     dpif_netlink_vport_init(vport);
 
-    ofpbuf_use_const(&b, ofpbuf_data(buf), ofpbuf_size(buf));
+    ofpbuf_use_const(&b, buf->data, buf->size);
     nlmsg = ofpbuf_try_pull(&b, sizeof *nlmsg);
     genl = ofpbuf_try_pull(&b, sizeof *genl);
     ovs_header = ofpbuf_try_pull(&b, sizeof *ovs_header);
@@ -2547,7 +2569,7 @@ dpif_netlink_dp_from_ofpbuf(struct dpif_netlink_dp *dp, const struct ofpbuf *buf
 
     dpif_netlink_dp_init(dp);
 
-    ofpbuf_use_const(&b, ofpbuf_data(buf), ofpbuf_size(buf));
+    ofpbuf_use_const(&b, buf->data, buf->size);
     nlmsg = ofpbuf_try_pull(&b, sizeof *nlmsg);
     genl = ofpbuf_try_pull(&b, sizeof *genl);
     ovs_header = ofpbuf_try_pull(&b, sizeof *ovs_header);
@@ -2705,7 +2727,7 @@ dpif_netlink_flow_from_ofpbuf(struct dpif_netlink_flow *flow,
 
     dpif_netlink_flow_init(flow);
 
-    ofpbuf_use_const(&b, ofpbuf_data(buf), ofpbuf_size(buf));
+    ofpbuf_use_const(&b, buf->data, buf->size);
     nlmsg = ofpbuf_try_pull(&b, sizeof *nlmsg);
     genl = ofpbuf_try_pull(&b, sizeof *genl);
     ovs_header = ofpbuf_try_pull(&b, sizeof *ovs_header);