@@ -1047,3 +1047,122 @@ AT_CHECK([ovs-appctl dpctl/dump-flows type=ovs | grep "eth_type(0x0800)" | DUMP_
1047
1047
1048
1048
OVS_TRAFFIC_VSWITCHD_STOP
1049
1049
AT_CLEANUP
1050
+
1051
+ AT_SETUP([offloads - split kernel vs offload datapath rules])
1052
+ OVS_TRAFFIC_VSWITCHD_START([], [], [-- set Open_vSwitch . other_config:hw-offload=true])
1053
+
1054
+ ADD_NAMESPACES(at_ns0, at_ns1)
1055
+
1056
+ ADD_VETH(p1, at_ns0, br0, "10.0.0.1/24")
1057
+ ADD_VETH(p2, at_ns1, br0, "10.0.0.2/24")
1058
+
1059
+ AT_CHECK([ovs-vsctl -- set interface ovs-p1 ofport_request=1 \
1060
+ -- set interface ovs-p2 ofport_request=2])
1061
+
1062
+ AT_DATA([groups.txt], [dnl
1063
+ group_id=1,type=select,selection_method=dp_hash,bucket=bucket_id:0,weight:100,actions=ct(commit,table=2)
1064
+ ])
1065
+ AT_DATA([flows.txt], [dnl
1066
+ table=0,arp,actions=NORMAL
1067
+ table=0,priority=100,cookie=0x12345678,in_port=ovs-p1,ip,nw_dst=10.0.0.2,actions=resubmit(,1)
1068
+ table=0,priority=100,cookie=0xabcedf,in_port=ovs-p2,ip,nw_dst=10.0.0.1,actions=ct(table=3)
1069
+ table=1,priority=200,ip,actions=group:1
1070
+ table=2,ip,actions=ovs-p2
1071
+ table=3,ip,actions=ovs-p1
1072
+ ])
1073
+ AT_CHECK([ovs-ofctl add-groups br0 groups.txt])
1074
+ AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
1075
+
1076
+ NS_CHECK_EXEC([at_ns0], [ping -q -c 3 -i 0.1 -W 2 10.0.0.2 | FORMAT_PING], [0], [dnl
1077
+ 3 packets transmitted, 3 received, 0% packet loss, time 0ms
1078
+ ])
1079
+
1080
+ AT_CHECK([ovs-appctl revalidator/wait])
1081
+
1082
+ dnl In this test we should not have the first recirculation(s) in the kernel
1083
+ dnl datapath, and the final flow in TC. They should all be in the kernel
1084
+ dnl datapath, as the dp_hash() action is currently not supported by TC.
1085
+ dnl The command below ensures they are all handled in the kernel datapath.
1086
+ AT_CHECK([ovs-appctl dpctl/dump-flows --names type=ovs filter='in_port(ovs-p1),ipv4' | \
1087
+ strip_recirc | strip_dp_hash | DUMP_CLEAN_SORTED], [0], [dnl
1088
+ recirc_id(<recirc>),in_port(ovs-p1),eth(),eth_type(0x0800),ipv4(dst=10.0.0.2,frag=no), packets:2, bytes:196, used:0.001s, actions:hash(l4(0)),recirc(<recirc>)
1089
+ recirc_id(<recirc>),in_port(ovs-p1),eth(),eth_type(0x0800),ipv4(frag=no), packets:2, bytes:196, used:0.001s, actions:ct(commit),recirc(<recirc>)
1090
+ recirc_id(<recirc>),in_port(ovs-p1),eth(),eth_type(0x0800),ipv4(frag=no), packets:2, bytes:196, used:0.001s, actions:ovs-p2
1091
+ ])
1092
+ AT_CHECK([ovs-appctl dpctl/dump-flows --names type=tc filter='in_port(ovs-p1),ipv4' | \
1093
+ strip_recirc | strip_dp_hash | DUMP_CLEAN_SORTED], [0], [dnl
1094
+ ])
1095
+
1096
+ dnl The next test will install two DP flows that are both accepted in the
1097
+ dnl TC datapath. But then the first one is moved to the kernel datapath,
1098
+ dnl we have to make sure both flows are moved to kernel (and no dual rules
1099
+ dnl exist).
1100
+
1101
+ AT_DATA([flows.txt], [dnl
1102
+ table=0,arp,actions=NORMAL
1103
+ table=0,priority=100,in_port=ovs-p1,ip,nw_dst=10.0.0.2,actions=ct(table=1)
1104
+ table=0,priority=100,in_port=ovs-p2,ip,nw_dst=10.0.0.1,actions=ovs-p1
1105
+ table=1,ip,actions=ovs-p2
1106
+ ])
1107
+
1108
+ AT_CHECK([ovs-vsctl set Open_vSwitch . other_config:max-idle=2000])
1109
+ AT_CHECK([ovs-ofctl del-flows br0])
1110
+ AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
1111
+ AT_CHECK([ovs-appctl revalidator/purge])
1112
+
1113
+ NS_CHECK_EXEC([at_ns0], [ping -q -c 3 -i 0.1 -W 2 10.0.0.2 | FORMAT_PING], [0], [dnl
1114
+ 3 packets transmitted, 3 received, 0% packet loss, time 0ms
1115
+ ])
1116
+
1117
+ AT_CHECK([ovs-appctl revalidator/wait])
1118
+ AT_CHECK([ovs-appctl dpctl/dump-flows --names type=tc filter='in_port(ovs-p1),ipv4' | \
1119
+ strip_recirc | strip_dp_hash | DUMP_CLEAN_SORTED], [0], [dnl
1120
+ recirc_id(<recirc>),in_port(ovs-p1),eth(),eth_type(0x0800),ipv4(dst=10.0.0.2,frag=no), packets:2, bytes:168, used:0.001s, actions:ct,recirc(<recirc>)
1121
+ recirc_id(<recirc>),in_port(ovs-p1),eth(),eth_type(0x0800),ipv4(frag=no), packets:2, bytes:168, used:0.001s, actions:ovs-p2
1122
+ ])
1123
+ AT_CHECK([ovs-appctl dpctl/dump-flows --names type=ovs filter='in_port(ovs-p1),ipv4' | \
1124
+ strip_recirc | strip_dp_hash | DUMP_CLEAN_SORTED], [0], [dnl
1125
+ ])
1126
+
1127
+ AT_DATA([flows.txt], [dnl
1128
+ table=0,priority=100,in_port=ovs-p1,ip,nw_dst=10.0.0.2,actions=controller(),ct(table=1)
1129
+ ])
1130
+
1131
+ AT_CHECK([ovs-ofctl del-flows br0 table=0,in_port=ovs-p1,ip,nw_dst=10.0.0.2])
1132
+ AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
1133
+ AT_CHECK([ovs-appctl revalidator/wait])
1134
+
1135
+ NS_CHECK_EXEC([at_ns0], [ping -q -c 3 -i 0.1 -W 2 10.0.0.2 | FORMAT_PING], [0], [dnl
1136
+ 3 packets transmitted, 3 received, 0% packet loss, time 0ms
1137
+ ])
1138
+
1139
+ AT_CHECK([ovs-appctl revalidator/wait])
1140
+
1141
+ dnl Unfortunately, until the unreachable TC rule times out, packets will be
1142
+ dnl handled by upcalls. So we first check for this case and then verify that
1143
+ dnl the rule finally moved.
1144
+ AT_CHECK([ovs-appctl dpctl/dump-flows --names type=tc filter='in_port(ovs-p1),ipv4' | \
1145
+ strip_recirc | strip_dp_hash | DUMP_CLEAN_SORTED], [0], [dnl
1146
+ recirc_id(<recirc>),in_port(ovs-p1),eth(),eth_type(0x0800),ipv4(frag=no), packets:2, bytes:168, used:0.001s, actions:ovs-p2
1147
+ ])
1148
+ AT_CHECK([ovs-appctl dpctl/dump-flows --names type=ovs filter='in_port(ovs-p1),ipv4' | \
1149
+ strip_recirc | strip_dp_hash | DUMP_CLEAN_SORTED], [0], [dnl
1150
+ recirc_id(<recirc>),in_port(ovs-p1),eth(),eth_type(0x0800),ipv4(dst=10.0.0.2,frag=no), packets:3, bytes:294, used:0.001s, actions:userspace(pid=4294967295,controller(reason=1,dont_send=0,continuation=0,recirc_id=<recirc>,rule_cookie=0,controller_id=0,max_len=65535)),ct,recirc(<recirc>)
1151
+ ])
1152
+
1153
+ check_rules_and_ping() {
1154
+ NS_CHECK_EXEC([at_ns0], [ping -q -c 1 -i 0.1 -W 2 10.0.0.2], [0], [ignore])
1155
+ AT_CHECK([ovs-appctl revalidator/wait])
1156
+ AT_CHECK([ovs-appctl dpctl/dump-flows -m filter='in_port(ovs-p1),ipv4'],
1157
+ [0], [stdout])
1158
+
1159
+ [[ "$(wc -l < stdout)" -ne 2 ]] && return 0
1160
+ grep -q "dp:tc" stdout
1161
+ }
1162
+
1163
+ OVS_WAIT_WHILE(
1164
+ [check_rules_and_ping],
1165
+ [ovs-appctl dpctl/dump-flows -m --names filter='in_port(ovs-p1),ipv4'])
1166
+
1167
+ OVS_TRAFFIC_VSWITCHD_STOP
1168
+ AT_CLEANUP
0 commit comments