Add table for pps limitaion
Table 59 will be used for pps limitation, the pipeline change is: all original flows with ``goto table 60`` will be changed to ``goto table 59``, while table 59 has a default rule is goto table 60. Then we can add pps flows to table 59 for all ports. Basic limit pipeline is: Ingress: packets get into br-int table 0, before send to table 60, in table 59, check the destanation MAC and local_vlan ID, if the dest is resident in this host, do the meter pps action and send to table 60. Egress: match src MAC and in_port, before send to table 60, in table 59, do the meter pps action and send to table 60. Why table 59? Because for ovs-agent flow structure, all packets will be send to table 60 to do next actions such as security group. Between table 0 and table 60, there are tables for ARP poison/spoofing prevention rules and MAC spoof filtering. We want similar security checks to take effect first, so it can drop packets before filling our limit queues (pps limitation based on data forwarding queue). And we do not want packets go through the long march of security group flows, in case of performance side effect when there are large amount of packets try to send, so limit it before goto security group flows. Partially-Implements: bp/packet-rate-limit Related-Bug: #1938966 Related-Bug: #1912460 Change-Id: I943f610c3b6bcf05e2e752ca3b57981f523f88a8
This commit is contained in:
parent
f324ddf769
commit
053a9d24ec
@ -208,9 +208,11 @@ the second security group. Ports have following attributes:
|
||||
Port 3
|
||||
- patch bridge port (e.g. patch-tun) in OVS bridge
|
||||
|
||||
|table_0| contains a low priority rule to continue packets processing in
|
||||
|table_60| aka TRANSIENT table. |table_0| is left for use to other
|
||||
features that take precedence over firewall, e.g. DVR. The only requirement is
|
||||
|table_0| - |table_59| contain some low priority rules to continue packets
|
||||
processing in |table_60| aka TRANSIENT table. |table_0| - |table_59| is
|
||||
left for use to other features that take precedence over firewall, e.g.
|
||||
DVR, ARP poison/spoofing prevention, MAC spoof filtering and packet rate
|
||||
limitation etc. The only requirement is
|
||||
that after such a feature is done with its processing, it needs to pass packets
|
||||
for processing to the TRANSIENT table. This TRANSIENT table distinguishes the
|
||||
ingress traffic from the egress traffic and loads into ``register 5`` a value
|
||||
@ -592,6 +594,7 @@ switched to the OVS driver.
|
||||
not work if one tries to replace openvswitch firewall with iptables.
|
||||
|
||||
.. |table_0| replace:: ``table 0`` (LOCAL_SWITCHING)
|
||||
.. |table_59| replace:: ``table 59`` (PACKET_RATE_LIMIT)
|
||||
.. |table_60| replace:: ``table 60`` (TRANSIENT)
|
||||
.. |table_71| replace:: ``table 71`` (BASE_EGRESS)
|
||||
.. |table_72| replace:: ``table 72`` (RULES_EGRESS)
|
||||
|
@ -60,6 +60,8 @@ MAC_SPOOF_TABLE = 25
|
||||
LOCAL_EGRESS_TABLE = 30
|
||||
LOCAL_IP_TABLE = 31
|
||||
|
||||
# packet rate limit table
|
||||
PACKET_RATE_LIMIT = 59
|
||||
# Table to decide whether further filtering is needed
|
||||
TRANSIENT_TABLE = 60
|
||||
LOCAL_MAC_DIRECT = 61
|
||||
@ -100,6 +102,7 @@ INT_BR_ALL_TABLES = (
|
||||
LOCAL_MAC_DIRECT,
|
||||
LOCAL_EGRESS_TABLE,
|
||||
LOCAL_IP_TABLE,
|
||||
PACKET_RATE_LIMIT,
|
||||
TRANSIENT_TABLE,
|
||||
TRANSIENT_EGRESS_TABLE,
|
||||
BASE_EGRESS_TABLE,
|
||||
|
@ -53,7 +53,7 @@ class OVSDVRInterfaceMixin(object):
|
||||
]
|
||||
instructions = [
|
||||
ofpp.OFPInstructionActions(ofp.OFPIT_APPLY_ACTIONS, actions),
|
||||
ofpp.OFPInstructionGotoTable(table_id=constants.TRANSIENT_TABLE)]
|
||||
ofpp.OFPInstructionGotoTable(table_id=constants.PACKET_RATE_LIMIT)]
|
||||
|
||||
self.install_instructions(table_id=constants.LOCAL_SWITCHING,
|
||||
priority=99,
|
||||
|
@ -53,7 +53,9 @@ class OVSIntegrationBridge(ovs_bridge.OVSAgentBridge,
|
||||
enable_dhcpv6=False):
|
||||
(_dp, ofp, ofpp) = self._get_dp()
|
||||
self.setup_canary_table()
|
||||
self.install_goto(dest_table_id=constants.TRANSIENT_TABLE)
|
||||
self.install_goto(dest_table_id=constants.PACKET_RATE_LIMIT)
|
||||
self.install_goto(dest_table_id=constants.TRANSIENT_TABLE,
|
||||
table_id=constants.PACKET_RATE_LIMIT)
|
||||
self.install_normal(table_id=constants.TRANSIENT_TABLE, priority=3)
|
||||
self.init_dhcp(enable_openflow_dhcp=enable_openflow_dhcp,
|
||||
enable_dhcpv6=enable_dhcpv6)
|
||||
@ -69,9 +71,9 @@ class OVSIntegrationBridge(ovs_bridge.OVSAgentBridge,
|
||||
priority=3)
|
||||
|
||||
# Local IP defaults
|
||||
self.install_goto(dest_table_id=constants.TRANSIENT_TABLE,
|
||||
self.install_goto(dest_table_id=constants.PACKET_RATE_LIMIT,
|
||||
table_id=constants.LOCAL_EGRESS_TABLE)
|
||||
self.install_goto(dest_table_id=constants.TRANSIENT_TABLE,
|
||||
self.install_goto(dest_table_id=constants.PACKET_RATE_LIMIT,
|
||||
table_id=constants.LOCAL_IP_TABLE)
|
||||
|
||||
def init_dhcp(self, enable_openflow_dhcp=False, enable_dhcpv6=False):
|
||||
@ -184,7 +186,7 @@ class OVSIntegrationBridge(ovs_bridge.OVSAgentBridge,
|
||||
]
|
||||
instructions = [
|
||||
ofpp.OFPInstructionActions(ofp.OFPIT_APPLY_ACTIONS, actions),
|
||||
ofpp.OFPInstructionGotoTable(table_id=constants.TRANSIENT_TABLE),
|
||||
ofpp.OFPInstructionGotoTable(table_id=constants.PACKET_RATE_LIMIT),
|
||||
]
|
||||
self.install_instructions(
|
||||
instructions=instructions,
|
||||
@ -265,7 +267,7 @@ class OVSIntegrationBridge(ovs_bridge.OVSAgentBridge,
|
||||
]
|
||||
instructions = [
|
||||
ofpp.OFPInstructionActions(ofp.OFPIT_APPLY_ACTIONS, actions),
|
||||
ofpp.OFPInstructionGotoTable(table_id=constants.TRANSIENT_TABLE),
|
||||
ofpp.OFPInstructionGotoTable(table_id=constants.PACKET_RATE_LIMIT),
|
||||
]
|
||||
self.install_instructions(table_id=table_id,
|
||||
priority=20,
|
||||
@ -366,7 +368,7 @@ class OVSIntegrationBridge(ovs_bridge.OVSAgentBridge,
|
||||
ip_proto=in_proto.IPPROTO_ICMPV6,
|
||||
icmpv6_type=icmpv6.ND_NEIGHBOR_ADVERT,
|
||||
ipv6_nd_target=masked_ip, in_port=port,
|
||||
dest_table_id=constants.TRANSIENT_TABLE)
|
||||
dest_table_id=constants.PACKET_RATE_LIMIT)
|
||||
|
||||
# Now that the rules are ready, direct icmpv6 neighbor advertisement
|
||||
# traffic from the port into the anti-spoof table.
|
||||
@ -522,7 +524,7 @@ class OVSIntegrationBridge(ovs_bridge.OVSAgentBridge,
|
||||
def install_garp_blocker_exception(self, vlan, ip, except_ip,
|
||||
table_id=constants.LOCAL_SWITCHING):
|
||||
match = self._garp_blocker_exception_match(vlan, ip, except_ip)
|
||||
self.install_goto(dest_table_id=constants.TRANSIENT_TABLE,
|
||||
self.install_goto(dest_table_id=constants.PACKET_RATE_LIMIT,
|
||||
table_id=table_id,
|
||||
priority=11,
|
||||
match=match)
|
||||
|
@ -47,12 +47,21 @@ class OVSIntegrationBridgeTest(ovs_bridge_test_base.OVSBridgeTestBase):
|
||||
call._send_msg(ofpp.OFPFlowMod(dp,
|
||||
cookie=self.stamp,
|
||||
instructions=[
|
||||
ofpp.OFPInstructionGotoTable(table_id=60),
|
||||
ofpp.OFPInstructionGotoTable(table_id=59),
|
||||
],
|
||||
match=ofpp.OFPMatch(),
|
||||
priority=0,
|
||||
table_id=0),
|
||||
active_bundle=None),
|
||||
call._send_msg(ofpp.OFPFlowMod(dp,
|
||||
cookie=self.stamp,
|
||||
instructions=[
|
||||
ofpp.OFPInstructionGotoTable(table_id=60),
|
||||
],
|
||||
match=ofpp.OFPMatch(),
|
||||
priority=0,
|
||||
table_id=59),
|
||||
active_bundle=None),
|
||||
call._send_msg(ofpp.OFPFlowMod(dp,
|
||||
cookie=self.stamp,
|
||||
instructions=[
|
||||
@ -130,7 +139,7 @@ class OVSIntegrationBridgeTest(ovs_bridge_test_base.OVSBridgeTestBase):
|
||||
call._send_msg(ofpp.OFPFlowMod(
|
||||
dp, cookie=self.stamp,
|
||||
instructions=[
|
||||
ofpp.OFPInstructionGotoTable(table_id=60),
|
||||
ofpp.OFPInstructionGotoTable(table_id=59),
|
||||
],
|
||||
match=ofpp.OFPMatch(),
|
||||
priority=0,
|
||||
@ -139,7 +148,7 @@ class OVSIntegrationBridgeTest(ovs_bridge_test_base.OVSBridgeTestBase):
|
||||
call._send_msg(ofpp.OFPFlowMod(
|
||||
dp, cookie=self.stamp,
|
||||
instructions=[
|
||||
ofpp.OFPInstructionGotoTable(table_id=60),
|
||||
ofpp.OFPInstructionGotoTable(table_id=59),
|
||||
],
|
||||
match=ofpp.OFPMatch(),
|
||||
priority=0,
|
||||
@ -163,7 +172,7 @@ class OVSIntegrationBridgeTest(ovs_bridge_test_base.OVSBridgeTestBase):
|
||||
ofpp.OFPActionSetField(
|
||||
vlan_vid=lvid | ofp.OFPVID_PRESENT),
|
||||
]),
|
||||
ofpp.OFPInstructionGotoTable(table_id=60),
|
||||
ofpp.OFPInstructionGotoTable(table_id=59),
|
||||
],
|
||||
match=ofpp.OFPMatch(
|
||||
in_port=port,
|
||||
@ -190,7 +199,7 @@ class OVSIntegrationBridgeTest(ovs_bridge_test_base.OVSBridgeTestBase):
|
||||
ofpp.OFPActionSetField(
|
||||
vlan_vid=lvid | ofp.OFPVID_PRESENT),
|
||||
]),
|
||||
ofpp.OFPInstructionGotoTable(table_id=60),
|
||||
ofpp.OFPInstructionGotoTable(table_id=59),
|
||||
],
|
||||
match=ofpp.OFPMatch(
|
||||
in_port=port,
|
||||
@ -246,7 +255,7 @@ class OVSIntegrationBridgeTest(ovs_bridge_test_base.OVSBridgeTestBase):
|
||||
ofpp.OFPInstructionActions(ofp.OFPIT_APPLY_ACTIONS, [
|
||||
ofpp.OFPActionSetField(eth_src=gateway_mac),
|
||||
]),
|
||||
ofpp.OFPInstructionGotoTable(table_id=60),
|
||||
ofpp.OFPInstructionGotoTable(table_id=59),
|
||||
],
|
||||
match=ofpp.OFPMatch(
|
||||
eth_dst=dst_mac,
|
||||
@ -316,7 +325,7 @@ class OVSIntegrationBridgeTest(ovs_bridge_test_base.OVSBridgeTestBase):
|
||||
ofpp.OFPInstructionActions(ofp.OFPIT_APPLY_ACTIONS, [
|
||||
ofpp.OFPActionSetField(eth_src=gateway_mac),
|
||||
]),
|
||||
ofpp.OFPInstructionGotoTable(table_id=60),
|
||||
ofpp.OFPInstructionGotoTable(table_id=59),
|
||||
],
|
||||
match=ofpp.OFPMatch(
|
||||
eth_dst=dst_mac,
|
||||
@ -359,7 +368,7 @@ class OVSIntegrationBridgeTest(ovs_bridge_test_base.OVSBridgeTestBase):
|
||||
ofpp.OFPInstructionActions(ofp.OFPIT_APPLY_ACTIONS, [
|
||||
ofpp.OFPActionSetField(eth_src=gateway_mac),
|
||||
]),
|
||||
ofpp.OFPInstructionGotoTable(table_id=60),
|
||||
ofpp.OFPInstructionGotoTable(table_id=59),
|
||||
],
|
||||
match=ofpp.OFPMatch(
|
||||
eth_dst=dst_mac,
|
||||
@ -502,7 +511,7 @@ class OVSIntegrationBridgeTest(ovs_bridge_test_base.OVSBridgeTestBase):
|
||||
call._send_msg(ofpp.OFPFlowMod(dp,
|
||||
cookie=self.stamp,
|
||||
instructions=[
|
||||
ofpp.OFPInstructionGotoTable(table_id=60),
|
||||
ofpp.OFPInstructionGotoTable(table_id=59),
|
||||
],
|
||||
match=ofpp.OFPMatch(
|
||||
eth_type=self.ether_types.ETH_TYPE_IPV6,
|
||||
@ -517,7 +526,7 @@ class OVSIntegrationBridgeTest(ovs_bridge_test_base.OVSBridgeTestBase):
|
||||
call._send_msg(ofpp.OFPFlowMod(dp,
|
||||
cookie=self.stamp,
|
||||
instructions=[
|
||||
ofpp.OFPInstructionGotoTable(table_id=60),
|
||||
ofpp.OFPInstructionGotoTable(table_id=59),
|
||||
],
|
||||
match=ofpp.OFPMatch(
|
||||
eth_type=self.ether_types.ETH_TYPE_IPV6,
|
||||
@ -768,7 +777,7 @@ class OVSIntegrationBridgeTest(ovs_bridge_test_base.OVSBridgeTestBase):
|
||||
expected = [
|
||||
call._send_msg(ofpp.OFPFlowMod(dp, cookie=self.stamp,
|
||||
instructions=[
|
||||
ofpp.OFPInstructionGotoTable(table_id=60)],
|
||||
ofpp.OFPInstructionGotoTable(table_id=59)],
|
||||
match=ofpp.OFPMatch(
|
||||
vlan_vid=vlan | ofp.OFPVID_PRESENT,
|
||||
eth_type=self.ether_types.ETH_TYPE_ARP,
|
||||
|
Loading…
Reference in New Issue
Block a user