From patchwork Sat Apr 23 05:26:17 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xiao Liang X-Patchwork-Id: 613977 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from archives.nicira.com (archives.nicira.com [96.126.127.54]) by ozlabs.org (Postfix) with ESMTP id 3qsLZv6ds9z9t6c for ; Sat, 23 Apr 2016 15:27:03 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b=b3/DkYCo; dkim-atps=neutral Received: from archives.nicira.com (localhost [127.0.0.1]) by archives.nicira.com (Postfix) with ESMTP id E84BB10B28; Fri, 22 Apr 2016 22:27:02 -0700 (PDT) X-Original-To: dev@openvswitch.org Delivered-To: dev@openvswitch.org Received: from mx3v3.cudamail.com (mx3.cudamail.com [64.34.241.5]) by archives.nicira.com (Postfix) with ESMTPS id 8412510B27 for ; Fri, 22 Apr 2016 22:27:02 -0700 (PDT) Received: from bar6.cudamail.com (localhost [127.0.0.1]) by mx3v3.cudamail.com (Postfix) with ESMTPS id 05233162542 for ; Fri, 22 Apr 2016 23:27:02 -0600 (MDT) X-ASG-Debug-ID: 1461389220-0b323710bb3e5660001-byXFYA Received: from mx3-pf2.cudamail.com ([192.168.14.1]) by bar6.cudamail.com with ESMTP id Vww9fgNir79uCU75 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Fri, 22 Apr 2016 23:27:00 -0600 (MDT) X-Barracuda-Envelope-From: shaw.leon@gmail.com X-Barracuda-RBL-Trusted-Forwarder: 192.168.14.1 Received: from unknown (HELO mail-pf0-f195.google.com) (209.85.192.195) by mx3-pf2.cudamail.com with ESMTPS (RC4-SHA encrypted); 23 Apr 2016 05:27:00 -0000 Received-SPF: pass (mx3-pf2.cudamail.com: SPF record at _netblocks.google.com designates 209.85.192.195 as permitted sender) X-Barracuda-Apparent-Source-IP: 209.85.192.195 X-Barracuda-RBL-IP: 209.85.192.195 Received: by mail-pf0-f195.google.com with SMTP id e190so11619786pfe.0 for ; Fri, 22 Apr 2016 22:27:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id; bh=8IR1nqflkanFWsQDbyWS87RngRy0ayG2XFA/gKjdEUg=; b=b3/DkYCo3kC2kxm7RlV2+ax9PFUeYKruzIpDlW4qsqeXj8OshYMq4KQah7NznwZTc9 lSuGR6mlMNNeDjvtOmZ4z99/T5TRjCsmqZotwdTWc3b1wgvlyZ4QtSxtOB54lq7pgdQq kyfYfW6O9abtL5u+khFDLhMWzaMhN7kwAr08E88Rm0kbs98Y3/JWZuEJCrDfLeRbFrIK fIQHwJ/jftvoaRlYnzMxN1uCrDMLhDXbvYdXPiyncqlGlC6P1NDW0q3f9gMimMqy9TBP x30DY6QTQFij62aO1xypcAZgfrz82yV9bQSC5v6q896R4dS6Q94lH19nWeZZaOV7H8ek kk1A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=8IR1nqflkanFWsQDbyWS87RngRy0ayG2XFA/gKjdEUg=; b=aq7xUXy5Zh4IppPk8RL0VLiNapSeiF63sqb/gjEYISKCQHfwcBKLkUKbUTV8POthHN xhG32CUZwnOzqaTOBaSBO5nSHM3PDMnSyBLqUN8T+Puf3vGdL0AQKPf7ZpYwL+OI2ryQ UrXaPf6er3f21/AytP91Q2NlIEGXzjiZVKhmfcNQAnRLDjQFjTbhkjv4dsmHas4vmbht fl5o4nLv0QvtolbcVkNs8l1F3WgHhGfAN0Vs7N7d4lFtJg2PQakXO0bdc+EGr0QcoT46 zrJB5YX8+DKIn2d1zjHkd8IiMaSC8qqNpfPMtbeokkSxWX6yeL3yuISc9HhYWZU5NmpD Vs4Q== X-Gm-Message-State: AOPr4FX/ekHVbGwIMEXtSplN7Z9M9ZH02eQPPTnQ5I3OWKVK+KdbYtx7ikZ0X6vlIIsUsg== X-Received: by 10.98.31.21 with SMTP id f21mr32847704pff.134.1461389219475; Fri, 22 Apr 2016 22:26:59 -0700 (PDT) Received: from arch.localdomain (li862-166.members.linode.com. [139.162.20.166]) by smtp.gmail.com with ESMTPSA id u64sm11971286pfa.86.2016.04.22.22.26.29 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 22 Apr 2016 22:26:58 -0700 (PDT) X-CudaMail-Envelope-Sender: shaw.leon@gmail.com From: Xiao Liang To: dev@openvswitch.org X-CudaMail-MID: CM-V2-421058214 X-CudaMail-DTE: 042216 X-CudaMail-Originating-IP: 209.85.192.195 Date: Sat, 23 Apr 2016 13:26:17 +0800 X-ASG-Orig-Subj: [##CM-V2-421058214##][PATCH v3] Add configurable OpenFlow port name. Message-Id: <1461389177-14344-1-git-send-email-shaw.leon@gmail.com> X-Mailer: git-send-email 2.8.0 X-GBUdb-Analysis: 0, 209.85.192.195, Ugly c=0.313739 p=-0.333333 Source Normal X-MessageSniffer-Rules: 0-0-0-28183-c X-Barracuda-Connect: UNKNOWN[192.168.14.1] X-Barracuda-Start-Time: 1461389220 X-Barracuda-Encrypted: DHE-RSA-AES256-SHA X-Barracuda-URL: https://web.cudamail.com:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at cudamail.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 1.60 X-Barracuda-Spam-Status: No, SCORE=1.60 using per-user scores of TAG_LEVEL=3.5 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=4.0 tests=BSF_RULE7568M, BSF_SC0_MV0713, BSF_SC5_MJ1963, DKIM_SIGNED, RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.28983 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature 0.50 BSF_RULE7568M Custom Rule 7568M 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS 0.50 BSF_SC0_MV0713 Custom rule MV0713 0.50 BSF_SC5_MJ1963 Custom Rule MJ1963 Cc: yamamoto@midokura.com Subject: [ovs-dev] [PATCH v3] Add configurable OpenFlow port name. X-BeenThere: dev@openvswitch.org X-Mailman-Version: 2.1.16 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: dev-bounces@openvswitch.org Sender: "dev" Add new column "ofname" in Interface table to configure port name reported to controllers with OpenFlow protocol, thus decouple OpenFlow port name from device name. For example: # ovs-vsctl set Interface eth0 ofname=wan # ovs-vsctl set Interface eth1 ofname=lan0 then controllers can recognize ports by their names. Signed-off-by: Xiao Liang --- v2: Added test for ofname Increased db schema version Updated NEWS v3: Rebase --- NEWS | 1 + lib/db-ctl-base.h | 2 +- ofproto/ofproto-provider.h | 1 + ofproto/ofproto.c | 67 ++++++++++++++++++++++++++++++++++++++++++++-- ofproto/ofproto.h | 9 ++++++- tests/ofproto.at | 60 +++++++++++++++++++++++++++++++++++++++++ utilities/ovs-vsctl.c | 1 + vswitchd/bridge.c | 10 +++++-- vswitchd/vswitch.ovsschema | 6 +++-- vswitchd/vswitch.xml | 14 ++++++++++ 10 files changed, 163 insertions(+), 8 deletions(-) diff --git a/NEWS b/NEWS index ea7f3a1..156781c 100644 --- a/NEWS +++ b/NEWS @@ -15,6 +15,7 @@ Post-v2.5.0 now implemented. Only flow mod and port mod messages are supported in bundles. * New OpenFlow extension NXM_NX_MPLS_TTL to provide access to MPLS TTL. + * Port name can now be set with "ofname" column in the Interface table. - ovs-ofctl: * queue-get-config command now allows a queue ID to be specified. * '--bundle' option can now be used with OpenFlow 1.3. diff --git a/lib/db-ctl-base.h b/lib/db-ctl-base.h index f8f576b..5bd62d5 100644 --- a/lib/db-ctl-base.h +++ b/lib/db-ctl-base.h @@ -177,7 +177,7 @@ struct weak_ref_table { struct cmd_show_table { const struct ovsdb_idl_table_class *table; const struct ovsdb_idl_column *name_column; - const struct ovsdb_idl_column *columns[3]; /* Seems like a good number. */ + const struct ovsdb_idl_column *columns[4]; /* Seems like a good number. */ const struct weak_ref_table wref_table; }; diff --git a/ofproto/ofproto-provider.h b/ofproto/ofproto-provider.h index daa0077..8795242 100644 --- a/ofproto/ofproto-provider.h +++ b/ofproto/ofproto-provider.h @@ -84,6 +84,7 @@ struct ofproto { struct hmap ports; /* Contains "struct ofport"s. */ struct shash port_by_name; struct simap ofp_requests; /* OpenFlow port number requests. */ + struct smap ofp_names; /* OpenFlow port names. */ uint16_t alloc_port_no; /* Last allocated OpenFlow port number. */ uint16_t max_ports; /* Max possible OpenFlow port num, plus one. */ struct hmap ofport_usage; /* Map ofport to last used time. */ diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c index ff6affd..a2799f4 100644 --- a/ofproto/ofproto.c +++ b/ofproto/ofproto.c @@ -550,6 +550,7 @@ ofproto_create(const char *datapath_name, const char *datapath_type, hmap_init(&ofproto->ofport_usage); shash_init(&ofproto->port_by_name); simap_init(&ofproto->ofp_requests); + smap_init(&ofproto->ofp_names); ofproto->max_ports = ofp_to_u16(OFPP_MAX); ofproto->eviction_group_timer = LLONG_MIN; ofproto->tables = NULL; @@ -1546,6 +1547,7 @@ ofproto_destroy__(struct ofproto *ofproto) hmap_destroy(&ofproto->ofport_usage); shash_destroy(&ofproto->port_by_name); simap_destroy(&ofproto->ofp_requests); + smap_destroy(&ofproto->ofp_names); OFPROTO_FOR_EACH_TABLE (table, ofproto) { oftable_destroy(table); @@ -1945,7 +1947,7 @@ ofproto_port_open_type(const char *datapath_type, const char *port_type) * 'ofp_portp' is non-null). */ int ofproto_port_add(struct ofproto *ofproto, struct netdev *netdev, - ofp_port_t *ofp_portp) + ofp_port_t *ofp_portp, const char *ofp_name) { ofp_port_t ofp_port = ofp_portp ? *ofp_portp : OFPP_NONE; int error; @@ -1956,6 +1958,9 @@ ofproto_port_add(struct ofproto *ofproto, struct netdev *netdev, simap_put(&ofproto->ofp_requests, netdev_name, ofp_to_u16(ofp_port)); + if (ofp_name) { + smap_replace(&ofproto->ofp_names, netdev_name, ofp_name); + } error = update_port(ofproto, netdev_name); } if (ofp_portp) { @@ -2009,6 +2014,8 @@ ofproto_port_del(struct ofproto *ofproto, ofp_port_t ofp_port) simap_delete(&ofproto->ofp_requests, ofp_request_node); } + smap_remove(&ofproto->ofp_names, name); + error = ofproto->ofproto_class->port_del(ofproto, ofp_port); if (!error && ofport) { /* 'name' is the netdev's name and update_port() is going to close the @@ -2285,6 +2292,7 @@ ofport_open(struct ofproto *ofproto, { enum netdev_flags flags; struct netdev *netdev; + const char *ofp_name; int error; error = netdev_open(ofproto_port->name, ofproto_port->type, &netdev); @@ -2307,7 +2315,13 @@ ofport_open(struct ofproto *ofproto, } pp->port_no = ofproto_port->ofp_port; netdev_get_etheraddr(netdev, &pp->hw_addr); - ovs_strlcpy(pp->name, ofproto_port->name, sizeof pp->name); + + ofp_name = smap_get(&ofproto->ofp_names, ofproto_port->name); + if (!ofp_name) { + ofp_name = ofproto_port->name; + } + ovs_strlcpy(pp->name, ofp_name, sizeof pp->name); + netdev_get_flags(netdev, &flags); pp->config = flags & NETDEV_UP ? 0 : OFPUTIL_PC_PORT_DOWN; pp->state = netdev_get_carrier(netdev) ? 0 : OFPUTIL_PS_LINK_DOWN; @@ -8011,3 +8025,52 @@ ofproto_port_set_realdev(struct ofproto *ofproto, ofp_port_t vlandev_ofp_port, } return error; } + +const char * +ofproto_port_get_ofpname(struct ofproto *ofproto, ofp_port_t ofp_port) +{ + struct ofport *ofport; + + ofport = ofproto_get_port(ofproto, ofp_port); + return (ofport ? ofport->pp.name : NULL); +} + +void +ofproto_port_set_ofpname(struct ofproto *ofproto, ofp_port_t ofp_port, + const char *ofp_name) +{ + struct ofport *ofport; + const char *devname; + size_t name_size; + + ofport = ofproto_get_port(ofproto, ofp_port); + if (!ofport) { + return; + } + + devname = netdev_get_name(ofport->netdev); + name_size = sizeof(ofport->pp.name); + + if (!devname || + (ofp_name && !strncmp(ofp_name, ofport->pp.name, name_size - 1)) || + (!ofp_name && !strncmp(devname, ofport->pp.name, name_size - 1))) { + /* No need to change port name. */ + return; + } + + /* Send a OFPPR_DELETE followed by OFPPR_ADD port_status message + * to notify controller a port name change. */ + connmgr_send_port_status(ofproto->connmgr, NULL, &ofport->pp, + OFPPR_DELETE); + + if (!ofp_name) { + smap_remove(&ofproto->ofp_names, devname); + ovs_strlcpy(ofport->pp.name, devname, name_size); + } else { + smap_replace(&ofproto->ofp_names, netdev_get_name(ofport->netdev), + ofp_name); + ovs_strlcpy(ofport->pp.name, ofp_name, name_size); + } + connmgr_send_port_status(ofproto->connmgr, NULL, &ofport->pp, + OFPPR_ADD); +} diff --git a/ofproto/ofproto.h b/ofproto/ofproto.h index 2d241c9..3382ef1 100644 --- a/ofproto/ofproto.h +++ b/ofproto/ofproto.h @@ -288,7 +288,8 @@ int ofproto_port_dump_done(struct ofproto_port_dump *); const char *ofproto_port_open_type(const char *datapath_type, const char *port_type); -int ofproto_port_add(struct ofproto *, struct netdev *, ofp_port_t *ofp_portp); +int ofproto_port_add(struct ofproto *, struct netdev *, ofp_port_t *ofp_portp, + const char *); int ofproto_port_del(struct ofproto *, ofp_port_t ofp_port); int ofproto_port_get_stats(const struct ofport *, struct netdev_stats *stats); @@ -521,6 +522,12 @@ int ofproto_port_set_realdev(struct ofproto *, ofp_port_t vlandev_ofp_port, enum ofputil_table_miss ofproto_table_get_miss_config(const struct ofproto *, uint8_t table_id); +const char *ofproto_port_get_ofpname(struct ofproto *ofproto, + ofp_port_t ofp_port); +void ofproto_port_set_ofpname(struct ofproto *ofproto, + ofp_port_t ofp_port, + const char *ofp_name); + #ifdef __cplusplus } #endif diff --git a/tests/ofproto.at b/tests/ofproto.at index c4260ab..5f38160 100644 --- a/tests/ofproto.at +++ b/tests/ofproto.at @@ -77,6 +77,66 @@ OFPT_GET_CONFIG_REPLY: frags=normal miss_send_len=0 OVS_VSWITCHD_STOP AT_CLEANUP +AT_SETUP([ofproto - set OpenFlow port name]) +OVS_VSWITCHD_START( + [add-port br0 p1 -- set Interface p1 type=dummy ofport_request=1 --\ + add-port br0 p2 -- set Interface p2 type=dummy ofport_request=2 ofname=n2]) +check_ofname () { + AT_CHECK([ovs-ofctl -vwarn show br0], [0], [stdout]) + echo >expout "OFPT_FEATURES_REPLY: dpid:fedcba9876543210 +n_tables:254, n_buffers:256 +capabilities: FLOW_STATS TABLE_STATS PORT_STATS QUEUE_STATS ARP_MATCH_IP +actions: output enqueue set_vlan_vid set_vlan_pcp strip_vlan mod_dl_src mod_dl_dst mod_nw_src mod_nw_dst mod_nw_tos mod_tp_src mod_tp_dst + 1($1): addr:aa:55:aa:55:00:0x + config: PORT_DOWN + state: LINK_DOWN + speed: 0 Mbps now, 0 Mbps max + 2(n2): addr:aa:55:aa:55:00:0x + config: PORT_DOWN + state: LINK_DOWN + speed: 0 Mbps now, 0 Mbps max + LOCAL(br0): addr:aa:55:aa:55:00:0x + config: PORT_DOWN + state: LINK_DOWN + speed: 0 Mbps now, 0 Mbps max +OFPT_GET_CONFIG_REPLY: frags=normal miss_send_len=0" + AT_CHECK([[sed ' +s/ (xid=0x[0-9a-fA-F]*)// +s/00:0.$/00:0x/' < stdout]], + [0], [expout]) +} + +AT_CHECK([ovs-vsctl set Interface p1 ofname=p2]) +check_ofname p2 + +AT_CHECK([ovs-ofctl -P standard monitor br0 --detach --no-chdir --pidfile]) +# Use NXT_SET_ASYNC_CONFIG to enable only port status message +ovs-appctl -t ovs-ofctl ofctl/send 01040028000000020000232000000013000000000000000500000007000000020000000000000005 +ovs-appctl -t ovs-ofctl ofctl/set-output-file monitor.log +AT_CHECK([ovs-vsctl set Interface p1 ofname=n2]) +check_ofname n2 +OVS_APP_EXIT_AND_WAIT([ovs-ofctl]) +AT_CHECK([[sed ' +s/ (xid=0x[0-9a-fA-F]*)// +s/ *duration.*// +s/00:0.$/00:0x/' < monitor.log]], + [0], [dnl +OFPT_PORT_STATUS: DEL: 1(p2): addr:aa:55:aa:55:00:0x + config: PORT_DOWN + state: LINK_DOWN + speed: 0 Mbps now, 0 Mbps max +OFPT_PORT_STATUS: ADD: 1(n2): addr:aa:55:aa:55:00:0x + config: PORT_DOWN + state: LINK_DOWN + speed: 0 Mbps now, 0 Mbps max +]) + +AT_CHECK([ovs-vsctl clear Interface p1 ofname]) +check_ofname p1 + +OVS_VSWITCHD_STOP +AT_CLEANUP + dnl This is really bare-bones. dnl It at least checks request and reply serialization and deserialization. AT_SETUP([ofproto - port stats - (OpenFlow 1.0)]) diff --git a/utilities/ovs-vsctl.c b/utilities/ovs-vsctl.c index c9c0f6d..44b386a 100644 --- a/utilities/ovs-vsctl.c +++ b/utilities/ovs-vsctl.c @@ -1008,6 +1008,7 @@ static struct cmd_show_table cmd_show_tables[] = { {&ovsrec_table_interface, &ovsrec_interface_col_name, {&ovsrec_interface_col_type, + &ovsrec_interface_col_ofname, &ovsrec_interface_col_options, &ovsrec_interface_col_error}, {NULL, NULL, NULL} diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c index 700f65c..bb49fe0 100644 --- a/vswitchd/bridge.c +++ b/vswitchd/bridge.c @@ -667,6 +667,10 @@ bridge_reconfigure(const struct ovsrec_open_vswitch *ovs_cfg) LIST_FOR_EACH (iface, port_elem, &port->ifaces) { iface_set_ofport(iface->cfg, iface->ofp_port); + + ofproto_port_set_ofpname(br->ofproto, iface->ofp_port, + iface->cfg->ofname); + /* Clear eventual previous errors */ ovsrec_interface_set_error(iface->cfg, NULL); iface_configure_cfm(iface); @@ -1777,7 +1781,8 @@ iface_do_create(const struct bridge *br, } *ofp_portp = iface_pick_ofport(iface_cfg); - error = ofproto_port_add(br->ofproto, netdev, ofp_portp); + error = ofproto_port_add(br->ofproto, netdev, ofp_portp, + iface_cfg->ofname); if (error) { goto error; } @@ -1860,7 +1865,8 @@ iface_create(struct bridge *br, const struct ovsrec_interface *iface_cfg, error = netdev_open(port->name, "internal", &netdev); if (!error) { ofp_port_t fake_ofp_port = OFPP_NONE; - ofproto_port_add(br->ofproto, netdev, &fake_ofp_port); + ofproto_port_add(br->ofproto, netdev, &fake_ofp_port, + iface_cfg->ofname); netdev_close(netdev); } else { VLOG_WARN("could not open network device %s (%s)", diff --git a/vswitchd/vswitch.ovsschema b/vswitchd/vswitch.ovsschema index e0937f4..d147d04 100644 --- a/vswitchd/vswitch.ovsschema +++ b/vswitchd/vswitch.ovsschema @@ -1,6 +1,6 @@ {"name": "Open_vSwitch", - "version": "7.13.0", - "cksum": "2202834738 22577", + "version": "7.13.1", + "cksum": "643309718 22653", "tables": { "Open_vSwitch": { "columns": { @@ -204,6 +204,8 @@ "mutable": false}, "type": { "type": "string"}, + "ofname": { + "type": {"key": "string", "min": 0, "max": 1}}, "options": { "type": {"key": "string", "value": "string", "min": 0, "max": "unlimited"}}, "ingress_policing_rate": { diff --git a/vswitchd/vswitch.xml b/vswitchd/vswitch.xml index 166f264..1869c81 100644 --- a/vswitchd/vswitch.xml +++ b/vswitchd/vswitch.xml @@ -1724,6 +1724,20 @@ on a host. + + +

+ OpenFlow port name for this interface. This name is truncated to + OFP_MAX_PORT_NAME_LEN-1, and reported to controllers in + port description. If not set, is used. +

+

+ OpenFlow does not have a way to announce a port name change, so if + is changed, Open vSwitch represents it over + OpenFlow as a port deletion followed immediately by a port addition. +

+
+ A positive interface index as defined for SNMP MIB-II in RFCs 1213 and 2863, if the interface has one, otherwise 0. The ifindex is useful for