@@ -1952,10 +1952,9 @@ func commonFlows(hostSubnets []*net.IPNet, bridge *bridgeConfiguration) ([]strin
19521952 defaultOpenFlowCookie , netConfig .ofPortPatch , bridgeMacAddress , config .Default .ConntrackZone ,
19531953 netConfig .masqCTMark , ofPortPhys ))
19541954
1955- // Allow (a) OVN->host traffic on the same node
1956- // (b) host->host traffic on the same node
1955+ // Allow OVN->Host traffic on the same node
19571956 if config .Gateway .Mode == config .GatewayModeShared || config .Gateway .Mode == config .GatewayModeLocal {
1958- dftFlows = append (dftFlows , hostNetworkNormalActionFlows (netConfig , bridgeMacAddress , hostSubnets , false )... )
1957+ dftFlows = append (dftFlows , ovnToHostNetworkNormalActionFlows (netConfig , bridgeMacAddress , hostSubnets , false )... )
19591958 }
19601959 } else {
19611960 // for UDN we additionally SNAT the packet from masquerade IP -> node IP
@@ -2049,10 +2048,9 @@ func commonFlows(hostSubnets []*net.IPNet, bridge *bridgeConfiguration) ([]strin
20492048 "actions=ct(commit, zone=%d, exec(set_field:%s->ct_mark)), output:%s" ,
20502049 defaultOpenFlowCookie , netConfig .ofPortPatch , bridgeMacAddress , config .Default .ConntrackZone , netConfig .masqCTMark , ofPortPhys ))
20512050
2052- // Allow (a) OVN->host traffic on the same node
2053- // (b) host->host traffic on the same node
2051+ // Allow OVN->Host traffic on the same node
20542052 if config .Gateway .Mode == config .GatewayModeShared || config .Gateway .Mode == config .GatewayModeLocal {
2055- dftFlows = append (dftFlows , hostNetworkNormalActionFlows (netConfig , bridgeMacAddress , hostSubnets , true )... )
2053+ dftFlows = append (dftFlows , ovnToHostNetworkNormalActionFlows (netConfig , bridgeMacAddress , hostSubnets , true )... )
20562054 }
20572055 } else {
20582056 // for UDN we additionally SNAT the packet from masquerade IP -> node IP
@@ -2247,15 +2245,23 @@ func pmtudDropFlows(bridge *bridgeConfiguration, ipAddrs []string) []string {
22472245 return flows
22482246}
22492247
2250- // hostNetworkNormalActionFlows returns the flows that allow IP{v4,v6} traffic:
2251- // a. from pods in the OVN network to pods in a localnet network, on the same node
2252- // b. from pods on the host to pods in a localnet network, on the same node
2253- // when the localnet is mapped to breth0.
2254- // The expected srcMAC is the MAC address of breth0 and the expected hostSubnets is the host subnets found on the node
2255- // primary interface.
2256- func hostNetworkNormalActionFlows (netConfig * bridgeUDNConfiguration , srcMAC string , hostSubnets []* net.IPNet , isV6 bool ) []string {
2248+ // ovnToHostNetworkNormalActionFlows returns the flows that allow IP{v4,v6} traffic from the OVN network to the host network
2249+ // when the destination is on the same node as the sender. This is necessary for pods in the default network to reach
2250+ // localnet pods on the same node, when the localnet is mapped to breth0. The expected srcMAC is the MAC address of breth0
2251+ // and the expected hostSubnets is the host subnets found on the node primary interface.
2252+ func ovnToHostNetworkNormalActionFlows (netConfig * bridgeUDNConfiguration , srcMAC string , hostSubnets []* net.IPNet , isV6 bool ) []string {
2253+ var inPort , ctMark , ipFamily , ipFamilyDest string
22572254 var flows []string
2258- var ipFamily , ipFamilyDest string
2255+
2256+ if config .Gateway .Mode == config .GatewayModeShared {
2257+ inPort = netConfig .ofPortPatch
2258+ ctMark = netConfig .masqCTMark
2259+ } else if config .Gateway .Mode == config .GatewayModeLocal {
2260+ inPort = "LOCAL"
2261+ ctMark = ctMarkHost
2262+ } else {
2263+ return nil
2264+ }
22592265
22602266 if isV6 {
22612267 ipFamily = "ipv6"
@@ -2265,69 +2271,38 @@ func hostNetworkNormalActionFlows(netConfig *bridgeUDNConfiguration, srcMAC stri
22652271 ipFamilyDest = "nw_dst"
22662272 }
22672273
2268- formatFlow := func (inPort , destIP , ctMark string ) string {
2269- // Matching IP traffic will be handled by the bridge instead of being output directly
2270- // to the NIC by the existing flow at prio=100.
2271- flowTemplate := "cookie=%s, priority=102, in_port=%s, dl_src=%s, %s, %s=%s, " +
2272- "actions=ct(commit, zone=%d, exec(set_field:%s->ct_mark)), output:NORMAL"
2273- return fmt .Sprintf (flowTemplate ,
2274- defaultOpenFlowCookie ,
2275- inPort ,
2276- srcMAC ,
2277- ipFamily ,
2278- ipFamilyDest ,
2279- destIP ,
2280- config .Default .ConntrackZone ,
2281- ctMark )
2282- }
2283-
2284- // Traffic path (a): OVN->localnet for shared gw mode
2285- if config .Gateway .Mode == config .GatewayModeShared {
2286- for _ , hostSubnet := range hostSubnets {
2287- if utilnet .IsIPv6 (hostSubnet .IP ) != isV6 {
2288- continue
2289- }
2290- flows = append (flows , formatFlow (netConfig .ofPortPatch , hostSubnet .String (), netConfig .masqCTMark ))
2291- }
2292- }
2293-
2294- // Traffic path (a): OVN->localnet for local gw mode
2295- // Traffic path (b): host->localnet for both gw modes
22962274 for _ , hostSubnet := range hostSubnets {
2297- if utilnet . IsIPv6 (hostSubnet .IP ) != isV6 {
2275+ if (hostSubnet .IP . To4 () == nil ) != isV6 {
22982276 continue
22992277 }
2300- flows = append (flows , formatFlow ("LOCAL" , hostSubnet .String (), ctMarkHost ))
2301- }
2302-
2303- if isV6 {
2304- // IPv6 neighbor discovery uses ICMPv6 messages sent to a special destination (ff02::1:ff00:0/104)
2305- // that is unrelated to the host subnets matched in the prio=102 flow above.
2306- // Allow neighbor discovery by matching against ICMP type and ingress port.
2307- formatICMPFlow := func (inPort , ctMark string , icmpType int ) string {
2308- icmpFlowTemplate := "cookie=%s, priority=102, in_port=%s, dl_src=%s, icmp6, icmpv6_type=%d, " +
2309- "actions=ct(commit, zone=%d, exec(set_field:%s->ct_mark)), output:NORMAL"
2310- return fmt .Sprintf (icmpFlowTemplate ,
2278+ // IP traffic from the OVN network to the host network should be handled normally by the bridge instead of
2279+ // being output directly to the NIC by the existing flow at prio=100.
2280+ flows = append (flows ,
2281+ fmt .Sprintf ("cookie=%s, priority=102, in_port=%s, dl_src=%s, %s, %s=%s, " +
2282+ "actions=ct(commit, zone=%d, exec(set_field:%s->ct_mark)), output:NORMAL" ,
23112283 defaultOpenFlowCookie ,
23122284 inPort ,
23132285 srcMAC ,
2314- icmpType ,
2286+ ipFamily ,
2287+ ipFamilyDest ,
2288+ hostSubnet .String (),
23152289 config .Default .ConntrackZone ,
2316- ctMark )
2317- }
2290+ ctMark ))
2291+ }
23182292
2293+ if isV6 {
2294+ // Neighbor discovery in IPv6 happens through ICMPv6 messages to a special destination (ff02::1:ff00:0/104),
2295+ // which has nothing to do with the host subnets we're matching against in the flow above at prio=102.
2296+ // Let's allow neighbor discovery by matching against icmp type and in_port.
23192297 for _ , icmpType := range []int {types .NeighborSolicitationICMPType , types .NeighborAdvertisementICMPType } {
2320- // Traffic path (a) for ICMP: OVN-> localnet for shared gw mode
2321- if config .Gateway .Mode == config .GatewayModeShared {
2322- flows = append (flows ,
2323- formatICMPFlow (netConfig .ofPortPatch , netConfig .masqCTMark , icmpType ))
2324- }
2325-
2326- // Traffic path (a) for ICMP: OVN->localnet for local gw mode
2327- // Traffic path (b) for ICMP: host->localnet for both gw modes
2328- flows = append (flows , formatICMPFlow ("LOCAL" , ctMarkHost , icmpType ))
2298+ flows = append (flows ,
2299+ fmt .Sprintf ("cookie=%s, priority=102, in_port=%s, dl_src=%s, icmp6, icmpv6_type=%d, " +
2300+ "actions=ct(commit, zone=%d, exec(set_field:%s->ct_mark)), output:NORMAL" ,
2301+ defaultOpenFlowCookie , inPort , srcMAC , icmpType ,
2302+ config .Default .ConntrackZone , ctMark ))
23292303 }
23302304 }
2305+
23312306 return flows
23322307}
23332308
0 commit comments