Skip to content

Commit

Permalink
tests: Rewrite unit tests to not expect bridge with odp zero.
Browse files Browse the repository at this point in the history
A future commit will make all bridges of a particular type share a
single backing datapath.  That backing datapath will have a datapath
port number of zero and bridges will be assigned other numbers.  This
commit modifies the tests so that they don't expect port zero.

It adopts the convention that bridges of type "dummy" with a name of the
form "br<n>" will be assigned a port number of 100+<n>.

Signed-off-by: Justin Pettit <[email protected]>
  • Loading branch information
Justin Pettit committed Nov 2, 2012
1 parent e1b1d06 commit e44768b
Show file tree
Hide file tree
Showing 5 changed files with 171 additions and 139 deletions.
79 changes: 44 additions & 35 deletions lib/dpif-netdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -197,11 +197,51 @@ create_dpif_netdev(struct dp_netdev *dp)
return &dpif->dpif;
}

static int
choose_port(struct dp_netdev *dp, const char *name)
{
int port_no;

if (dp->class != &dpif_netdev_class) {
const char *p;
int start_no = 0;

/* If the port name begins with "br", start the number search at
* 100 to make writing tests easier. */
if (!strncmp(name, "br", 2)) {
start_no = 100;
}

/* If the port name contains a number, try to assign that port number.
* This can make writing unit tests easier because port numbers are
* predictable. */
for (p = name; *p != '\0'; p++) {
if (isdigit((unsigned char) *p)) {
port_no = start_no + strtol(p, NULL, 10);
if (port_no > 0 && port_no < MAX_PORTS
&& !dp->ports[port_no]) {
return port_no;
}
break;
}
}
}

for (port_no = 1; port_no < MAX_PORTS; port_no++) {
if (!dp->ports[port_no]) {
return port_no;
}
}

return -1;
}

static int
create_dp_netdev(const char *name, const struct dpif_class *class,
struct dp_netdev **dpp)
{
struct dp_netdev *dp;
int port_no;
int error;
int i;

Expand All @@ -214,7 +254,9 @@ create_dp_netdev(const char *name, const struct dpif_class *class,
}
hmap_init(&dp->flow_table);
list_init(&dp->port_list);
error = do_add_port(dp, name, "internal", OVSP_LOCAL);

port_no = !strncmp(name, "br", 2) ? choose_port(dp, name) : OVSP_LOCAL;
error = do_add_port(dp, name, "internal", port_no);
if (error) {
dp_netdev_free(dp);
return error;
Expand Down Expand Up @@ -370,39 +412,6 @@ do_add_port(struct dp_netdev *dp, const char *devname, const char *type,
return 0;
}

static int
choose_port(struct dpif *dpif, struct netdev *netdev)
{
struct dp_netdev *dp = get_dp_netdev(dpif);
int port_no;

if (dpif->dpif_class != &dpif_netdev_class) {
/* If the port name contains a number, try to assign that port number.
* This can make writing unit tests easier because port numbers are
* predictable. */
const char *p;

for (p = netdev_get_name(netdev); *p != '\0'; p++) {
if (isdigit((unsigned char) *p)) {
port_no = strtol(p, NULL, 10);
if (port_no > 0 && port_no < MAX_PORTS
&& !dp->ports[port_no]) {
return port_no;
}
break;
}
}
}

for (port_no = 0; port_no < MAX_PORTS; port_no++) {
if (!dp->ports[port_no]) {
return port_no;
}
}

return -1;
}

static int
dpif_netdev_port_add(struct dpif *dpif, struct netdev *netdev,
uint32_t *port_nop)
Expand All @@ -418,7 +427,7 @@ dpif_netdev_port_add(struct dpif *dpif, struct netdev *netdev,
}
port_no = *port_nop;
} else {
port_no = choose_port(dpif, netdev);
port_no = choose_port(dp, netdev_get_name(netdev));
}
if (port_no >= 0) {
*port_nop = port_no;
Expand Down
62 changes: 41 additions & 21 deletions tests/learn.at
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,9 @@ AT_CLEANUP

AT_SETUP([learning action - standard VLAN+MAC learning])
OVS_VSWITCHD_START(
[add-port br0 eth0 -- set Interface eth0 type=dummy -- \
add-port br0 eth1 -- set Interface eth1 type=dummy -- \
add-port br0 eth2 -- set Interface eth2 type=dummy])
[add-port br0 p1 -- set Interface p1 type=dummy ofport_request=1 -- \
add-port br0 p2 -- set Interface p2 type=dummy ofport_request=2 -- \
add-port br0 p3 -- set Interface p3 type=dummy ofport_request=3])
# Set up flow table for VLAN+MAC learning.
AT_DATA([flows.txt], [[
table=0 actions=learn(table=1, hard_timeout=60, NXM_OF_VLAN_TCI[0..11], NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[], output:NXM_OF_IN_PORT[]), resubmit(,1)
Expand All @@ -72,9 +72,14 @@ table=1 priority=0 actions=flood
AT_CHECK([ovs-ofctl add-flows br0 flows.txt])

# Trace an ARP packet arriving on port 3, to create a MAC learning entry.
AT_CHECK([ovs-appctl ofproto/trace br0 'in_port(3),eth(src=50:54:00:00:00:05,dst=ff:ff:ff:ff:ff:ff),eth_type(0x0806),arp(sip=192.168.0.1,tip=192.168.0.2,op=1,sha=50:54:00:00:00:05,tha=00:00:00:00:00:00)' -generate], [0], [stdout])
AT_CHECK([tail -1 stdout], [0], [Datapath actions: 2,0,1
])
flow="in_port(3),eth(src=50:54:00:00:00:05,dst=ff:ff:ff:ff:ff:ff),eth_type(0x0806),arp(sip=192.168.0.1,tip=192.168.0.2,op=1,sha=50:54:00:00:00:05,tha=00:00:00:00:00:00)"
AT_CHECK([ovs-appctl ofproto/trace br0 "$flow" -generate], [0], [stdout])
actual=`tail -1 stdout | sed 's/Datapath actions: //'`

expected="1,2,100"
AT_CHECK([ovs-dpctl normalize-actions "$flow" "$expected"], [0], [stdout])
mv stdout expout
AT_CHECK([ovs-dpctl normalize-actions "$flow" "$actual"], [0], [expout])

# Check for the MAC learning entry.
AT_CHECK([ovs-ofctl dump-flows br0 table=1 | ofctl_strip | sort], [0], [dnl
Expand All @@ -98,9 +103,14 @@ NXST_FLOW reply:
])

# Trace a packet arrival that updates the first learned MAC entry.
AT_CHECK([ovs-appctl ofproto/trace br0 'in_port(2),eth(src=50:54:00:00:00:05,dst=ff:ff:ff:ff:ff:ff),eth_type(0x0806),arp(sip=192.168.0.1,tip=192.168.0.2,op=1,sha=50:54:00:00:00:05,tha=00:00:00:00:00:00)' -generate], [0], [stdout])
AT_CHECK([tail -1 stdout], [0], [Datapath actions: 3,0,1
])
flow="in_port(2),eth(src=50:54:00:00:00:05,dst=ff:ff:ff:ff:ff:ff),eth_type(0x0806),arp(sip=192.168.0.1,tip=192.168.0.2,op=1,sha=50:54:00:00:00:05,tha=00:00:00:00:00:00)"
AT_CHECK([ovs-appctl ofproto/trace br0 "$flow" -generate], [0], [stdout])
actual=`tail -1 stdout | sed 's/Datapath actions: //'`

expected="1,3,100"
AT_CHECK([ovs-dpctl normalize-actions "$flow" "$expected"], [0], [stdout])
mv stdout expout
AT_CHECK([ovs-dpctl normalize-actions "$flow" "$actual"], [0], [expout])

# Check that the MAC learning entry was updated.
AT_CHECK([ovs-ofctl dump-flows br0 table=1 | ofctl_strip | sort], [0], [dnl
Expand All @@ -114,16 +124,21 @@ AT_CLEANUP

AT_SETUP([learning action - TCPv4 port learning])
OVS_VSWITCHD_START(
[add-port br0 eth0 -- set Interface eth0 type=dummy -- \
add-port br0 eth1 -- set Interface eth1 type=dummy -- \
add-port br0 eth2 -- set Interface eth2 type=dummy])
[add-port br0 p1 -- set Interface p1 type=dummy -- \
add-port br0 p2 -- set Interface p2 type=dummy -- \
add-port br0 p3 -- set Interface p3 type=dummy])
# Set up flow table for TCPv4 port learning.
AT_CHECK([[ovs-ofctl add-flow br0 'table=0 tcp actions=learn(table=1, hard_timeout=60, eth_type=0x800, nw_proto=6, NXM_OF_IP_SRC[]=NXM_OF_IP_DST[], NXM_OF_IP_DST[]=NXM_OF_IP_SRC[], NXM_OF_TCP_SRC[]=NXM_OF_TCP_DST[], NXM_OF_TCP_DST[]=NXM_OF_TCP_SRC[]), flood']])

# Trace a TCPv4 packet arriving on port 3.
AT_CHECK([ovs-appctl ofproto/trace br0 'in_port(3),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:06),eth_type(0x0800),ipv4(src=192.168.0.2,dst=192.168.0.1,proto=6,tos=0,ttl=64,frag=no),tcp(src=40000,dst=80)' -generate], [0], [stdout])
AT_CHECK([tail -1 stdout], [0], [Datapath actions: 2,0,1
])
flow="in_port(3),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:06),eth_type(0x0800),ipv4(src=192.168.0.2,dst=192.168.0.1,proto=6,tos=0,ttl=64,frag=no),tcp(src=40000,dst=80)"
AT_CHECK([ovs-appctl ofproto/trace br0 "$flow" -generate], [0], [stdout])
actual=`tail -1 stdout | sed 's/Datapath actions: //'`

expected="1,2,100"
AT_CHECK([ovs-dpctl normalize-actions "$flow" "$expected"], [0], [stdout])
mv stdout expout
AT_CHECK([ovs-dpctl normalize-actions "$flow" "$actual"], [0], [expout])

# Check for the learning entry.
AT_CHECK([ovs-ofctl dump-flows br0 table=1 | ofctl_strip | sort], [0], [dnl
Expand All @@ -135,18 +150,23 @@ AT_CLEANUP

AT_SETUP([learning action - TCPv6 port learning])
OVS_VSWITCHD_START(
[add-port br0 eth0 -- set Interface eth0 type=dummy -- \
add-port br0 eth1 -- set Interface eth1 type=dummy -- \
add-port br0 eth2 -- set Interface eth2 type=dummy])
[add-port br0 p1 -- set Interface p1 type=dummy -- \
add-port br0 p2 -- set Interface p2 type=dummy -- \
add-port br0 p3 -- set Interface p3 type=dummy])
# Set up flow table for TCPv6 port learning.
# Also add a 128-bit-wide "load" action and a 128-bit literal match to check
# that they work.
AT_CHECK([[ovs-ofctl add-flow br0 'table=0 tcp6 actions=learn(table=1, hard_timeout=60, eth_type=0x86dd, nw_proto=6, NXM_NX_IPV6_SRC[]=NXM_NX_IPV6_DST[], ipv6_dst=2001:0db8:85a3:0000:0000:8a2e:0370:7334, NXM_OF_TCP_SRC[]=NXM_OF_TCP_DST[], NXM_OF_TCP_DST[]=NXM_OF_TCP_SRC[], load(0x20010db885a308d313198a2e03707348->NXM_NX_IPV6_DST[])), flood']])

# Trace a TCPv6 packet arriving on port 3.
AT_CHECK([ovs-appctl ofproto/trace br0 'in_port(3),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:06),eth_type(0x86dd),ipv6(src=fec0::2,dst=fec0::1,label=0,proto=6,tclass=0,hlimit=255,frag=no),tcp(src=40000,dst=80)' -generate], [0], [stdout])
AT_CHECK([tail -1 stdout], [0], [Datapath actions: 2,0,1
])
flow="in_port(3),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:06),eth_type(0x86dd),ipv6(src=fec0::2,dst=fec0::1,label=0,proto=6,tclass=0,hlimit=255,frag=no),tcp(src=40000,dst=80)"
AT_CHECK([ovs-appctl ofproto/trace br0 "$flow" -generate], [0], [stdout])
actual=`tail -1 stdout | sed 's/Datapath actions: //'`

expected="1,2,100"
AT_CHECK([ovs-dpctl normalize-actions "$flow" "$expected"], [0], [stdout])
mv stdout expout
AT_CHECK([ovs-dpctl normalize-actions "$flow" "$actual"], [0], [expout])

# Check for the learning entry.
AT_CHECK([ovs-ofctl dump-flows br0 | ofctl_strip | sort], [0], [dnl
Expand Down
Loading

0 comments on commit e44768b

Please sign in to comment.