@@ -1937,10 +1937,9 @@ func commonFlows(hostSubnets []*net.IPNet, bridge *bridgeConfiguration) ([]strin
19371937 defaultOpenFlowCookie , netConfig .ofPortPatch , bridgeMacAddress , config .Default .ConntrackZone ,
19381938 netConfig .masqCTMark , ofPortPhys ))
19391939
1940- // Allow (a) OVN->host traffic on the same node
1941- // (b) host->host traffic on the same node
1940+ // Allow OVN->Host traffic on the same node
19421941 if config .Gateway .Mode == config .GatewayModeShared || config .Gateway .Mode == config .GatewayModeLocal {
1943- dftFlows = append (dftFlows , hostNetworkNormalActionFlows (netConfig , bridgeMacAddress , hostSubnets , false )... )
1942+ dftFlows = append (dftFlows , ovnToHostNetworkNormalActionFlows (netConfig , bridgeMacAddress , hostSubnets , false )... )
19441943 }
19451944 } else {
19461945 // for UDN we additionally SNAT the packet from masquerade IP -> node IP
@@ -2034,10 +2033,9 @@ func commonFlows(hostSubnets []*net.IPNet, bridge *bridgeConfiguration) ([]strin
20342033 "actions=ct(commit, zone=%d, exec(set_field:%s->ct_mark)), output:%s" ,
20352034 defaultOpenFlowCookie , netConfig .ofPortPatch , bridgeMacAddress , config .Default .ConntrackZone , netConfig .masqCTMark , ofPortPhys ))
20362035
2037- // Allow (a) OVN->host traffic on the same node
2038- // (b) host->host traffic on the same node
2036+ // Allow OVN->Host traffic on the same node
20392037 if config .Gateway .Mode == config .GatewayModeShared || config .Gateway .Mode == config .GatewayModeLocal {
2040- dftFlows = append (dftFlows , hostNetworkNormalActionFlows (netConfig , bridgeMacAddress , hostSubnets , true )... )
2038+ dftFlows = append (dftFlows , ovnToHostNetworkNormalActionFlows (netConfig , bridgeMacAddress , hostSubnets , true )... )
20412039 }
20422040 } else {
20432041 // for UDN we additionally SNAT the packet from masquerade IP -> node IP
@@ -2217,15 +2215,23 @@ func commonFlows(hostSubnets []*net.IPNet, bridge *bridgeConfiguration) ([]strin
22172215 return dftFlows , nil
22182216}
22192217
2220- // hostNetworkNormalActionFlows returns the flows that allow IP{v4,v6} traffic:
2221- // a. from pods in the OVN network to pods in a localnet network, on the same node
2222- // b. from pods on the host to pods in a localnet network, on the same node
2223- // when the localnet is mapped to breth0.
2224- // The expected srcMAC is the MAC address of breth0 and the expected hostSubnets is the host subnets found on the node
2225- // primary interface.
2226- func hostNetworkNormalActionFlows (netConfig * bridgeUDNConfiguration , srcMAC string , hostSubnets []* net.IPNet , isV6 bool ) []string {
2218+ // ovnToHostNetworkNormalActionFlows returns the flows that allow IP{v4,v6} traffic from the OVN network to the host network
2219+ // when the destination is on the same node as the sender. This is necessary for pods in the default network to reach
2220+ // localnet pods on the same node, when the localnet is mapped to breth0. The expected srcMAC is the MAC address of breth0
2221+ // and the expected hostSubnets is the host subnets found on the node primary interface.
2222+ func ovnToHostNetworkNormalActionFlows (netConfig * bridgeUDNConfiguration , srcMAC string , hostSubnets []* net.IPNet , isV6 bool ) []string {
2223+ var inPort , ctMark , ipFamily , ipFamilyDest string
22272224 var flows []string
2228- var ipFamily , ipFamilyDest string
2225+
2226+ if config .Gateway .Mode == config .GatewayModeShared {
2227+ inPort = netConfig .ofPortPatch
2228+ ctMark = netConfig .masqCTMark
2229+ } else if config .Gateway .Mode == config .GatewayModeLocal {
2230+ inPort = "LOCAL"
2231+ ctMark = ctMarkHost
2232+ } else {
2233+ return nil
2234+ }
22292235
22302236 if isV6 {
22312237 ipFamily = "ipv6"
@@ -2235,69 +2241,38 @@ func hostNetworkNormalActionFlows(netConfig *bridgeUDNConfiguration, srcMAC stri
22352241 ipFamilyDest = "nw_dst"
22362242 }
22372243
2238- formatFlow := func (inPort , destIP , ctMark string ) string {
2239- // Matching IP traffic will be handled by the bridge instead of being output directly
2240- // to the NIC by the existing flow at prio=100.
2241- flowTemplate := "cookie=%s, priority=102, in_port=%s, dl_src=%s, %s, %s=%s, " +
2242- "actions=ct(commit, zone=%d, exec(set_field:%s->ct_mark)), output:NORMAL"
2243- return fmt .Sprintf (flowTemplate ,
2244- defaultOpenFlowCookie ,
2245- inPort ,
2246- srcMAC ,
2247- ipFamily ,
2248- ipFamilyDest ,
2249- destIP ,
2250- config .Default .ConntrackZone ,
2251- ctMark )
2252- }
2253-
2254- // Traffic path (a): OVN->localnet for shared gw mode
2255- if config .Gateway .Mode == config .GatewayModeShared {
2256- for _ , hostSubnet := range hostSubnets {
2257- if utilnet .IsIPv6 (hostSubnet .IP ) != isV6 {
2258- continue
2259- }
2260- flows = append (flows , formatFlow (netConfig .ofPortPatch , hostSubnet .String (), netConfig .masqCTMark ))
2261- }
2262- }
2263-
2264- // Traffic path (a): OVN->localnet for local gw mode
2265- // Traffic path (b): host->localnet for both gw modes
22662244 for _ , hostSubnet := range hostSubnets {
2267- if utilnet . IsIPv6 (hostSubnet .IP ) != isV6 {
2245+ if (hostSubnet .IP . To4 () == nil ) != isV6 {
22682246 continue
22692247 }
2270- flows = append (flows , formatFlow ("LOCAL" , hostSubnet .String (), ctMarkHost ))
2271- }
2272-
2273- if isV6 {
2274- // IPv6 neighbor discovery uses ICMPv6 messages sent to a special destination (ff02::1:ff00:0/104)
2275- // that is unrelated to the host subnets matched in the prio=102 flow above.
2276- // Allow neighbor discovery by matching against ICMP type and ingress port.
2277- formatICMPFlow := func (inPort , ctMark string , icmpType int ) string {
2278- icmpFlowTemplate := "cookie=%s, priority=102, in_port=%s, dl_src=%s, icmp6, icmpv6_type=%d, " +
2279- "actions=ct(commit, zone=%d, exec(set_field:%s->ct_mark)), output:NORMAL"
2280- return fmt .Sprintf (icmpFlowTemplate ,
2248+ // IP traffic from the OVN network to the host network should be handled normally by the bridge instead of
2249+ // being output directly to the NIC by the existing flow at prio=100.
2250+ flows = append (flows ,
2251+ fmt .Sprintf ("cookie=%s, priority=102, in_port=%s, dl_src=%s, %s, %s=%s, " +
2252+ "actions=ct(commit, zone=%d, exec(set_field:%s->ct_mark)), output:NORMAL" ,
22812253 defaultOpenFlowCookie ,
22822254 inPort ,
22832255 srcMAC ,
2284- icmpType ,
2256+ ipFamily ,
2257+ ipFamilyDest ,
2258+ hostSubnet .String (),
22852259 config .Default .ConntrackZone ,
2286- ctMark )
2287- }
2260+ ctMark ))
2261+ }
22882262
2263+ if isV6 {
2264+ // Neighbor discovery in IPv6 happens through ICMPv6 messages to a special destination (ff02::1:ff00:0/104),
2265+ // which has nothing to do with the host subnets we're matching against in the flow above at prio=102.
2266+ // Let's allow neighbor discovery by matching against icmp type and in_port.
22892267 for _ , icmpType := range []int {types .NeighborSolicitationICMPType , types .NeighborAdvertisementICMPType } {
2290- // Traffic path (a) for ICMP: OVN-> localnet for shared gw mode
2291- if config .Gateway .Mode == config .GatewayModeShared {
2292- flows = append (flows ,
2293- formatICMPFlow (netConfig .ofPortPatch , netConfig .masqCTMark , icmpType ))
2294- }
2295-
2296- // Traffic path (a) for ICMP: OVN->localnet for local gw mode
2297- // Traffic path (b) for ICMP: host->localnet for both gw modes
2298- flows = append (flows , formatICMPFlow ("LOCAL" , ctMarkHost , icmpType ))
2268+ flows = append (flows ,
2269+ fmt .Sprintf ("cookie=%s, priority=102, in_port=%s, dl_src=%s, icmp6, icmpv6_type=%d, " +
2270+ "actions=ct(commit, zone=%d, exec(set_field:%s->ct_mark)), output:NORMAL" ,
2271+ defaultOpenFlowCookie , inPort , srcMAC , icmpType ,
2272+ config .Default .ConntrackZone , ctMark ))
22992273 }
23002274 }
2275+
23012276 return flows
23022277}
23032278
0 commit comments