Skip to content

Commit

Permalink
fix vlan subnet use logical gw can not access outside cluster node
Browse files Browse the repository at this point in the history
  • Loading branch information
bobz965 committed Jul 4, 2023
1 parent fe924e9 commit ba1a285
Showing 1 changed file with 58 additions and 4 deletions.
62 changes: 58 additions & 4 deletions pkg/daemon/controller_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,12 @@ func (c *Controller) reconcileRouters(event *subnetEvent) error {
klog.Errorf("failed to list subnets %v", err)
return err
}

pns, err := c.providerNetworksLister.List(labels.Everything())
if err != nil {
klog.Errorf("failed to list provider networks %v", err)
return err
}
vlanGws := make([]string, 0, len(pns))
if event != nil {
var ok bool
var oldSubnet, newSubnet *kubeovnv1.Subnet
Expand Down Expand Up @@ -196,14 +201,17 @@ func (c *Controller) reconcileRouters(event *subnetEvent) error {
joinCIDR := make([]string, 0, 2)
cidrs := make([]string, 0, len(subnets)*2)
for _, subnet := range subnets {
if (subnet.Spec.Vlan != "" && !subnet.Spec.LogicalGateway) || subnet.Spec.Vpc != c.config.ClusterRouter || !subnet.Status.IsReady() {
if subnet.Spec.Vpc != c.config.ClusterRouter || !subnet.Status.IsReady() {
continue
}

for _, cidrBlock := range strings.Split(subnet.Spec.CIDRBlock, ",") {
if _, ipNet, err := net.ParseCIDR(cidrBlock); err != nil {
klog.Errorf("%s is not a valid cidr block", cidrBlock)
} else {
if subnet.Spec.Vlan != "" {
vlanGws = append(vlanGws, subnet.Spec.Gateway)
}
if nodeIPv4 != "" && util.CIDRContainIP(cidrBlock, nodeIPv4) {
continue
}
Expand All @@ -218,6 +226,29 @@ func (c *Controller) reconcileRouters(event *subnetEvent) error {
}
}

var existVlanRoutes []netlink.Route
for _, pn := range pns {
mappings, err := getOvnMappings("ovn-bridge-mappings")
if err != nil {
return err
}
brName := mappings[pn.Name]
if brName != "" {
nic, err := netlink.LinkByName(brName)
if err != nil {
klog.Errorf("failed to get nic %s", brName)
return fmt.Errorf("failed to get nic %s", brName)
}
for _, gw := range vlanGws {
vlanRoutes, err := getNicExistRoutes(nic, gw)
if err != nil {
klog.Errorf("failed to get exist routes for nic %s", brName)
return err
}
existVlanRoutes = append(existVlanRoutes, vlanRoutes...)
}
}
}
gateway, ok := node.Annotations[util.GatewayAnnotation]
if !ok {
klog.Errorf("annotation for node %s ovn.kubernetes.io/gateway not exists", node.Name)
Expand All @@ -234,7 +265,7 @@ func (c *Controller) reconcileRouters(event *subnetEvent) error {
return err
}

toAdd, toDel := routeDiff(existRoutes, cidrs, joinCIDR, gateway, net.ParseIP(nodeIPv4), net.ParseIP(nodeIPv6))
toAdd, toDel := routeDiff(existRoutes, existVlanRoutes, cidrs, joinCIDR, gateway, net.ParseIP(nodeIPv4), net.ParseIP(nodeIPv6))
for _, r := range toDel {
if err = netlink.RouteDel(&netlink.Route{Dst: r.Dst}); err != nil {
klog.Errorf("failed to del route %v", err)
Expand Down Expand Up @@ -268,7 +299,7 @@ func getNicExistRoutes(nic netlink.Link, gateway string) ([]netlink.Route, error
return existRoutes, nil
}

func routeDiff(existRoutes []netlink.Route, cidrs, joinCIDR []string, gateway string, srcIPv4, srcIPv6 net.IP) (toAdd, toDel []netlink.Route) {
func routeDiff(existRoutes []netlink.Route, existVlanRoutes []netlink.Route, cidrs, joinCIDR []string, gateway string, srcIPv4, srcIPv6 net.IP) (toAdd, toDel []netlink.Route) {
for _, route := range existRoutes {
if route.Scope == netlink.SCOPE_LINK || route.Dst == nil || route.Dst.IP.IsLinkLocalUnicast() {
continue
Expand All @@ -284,6 +315,17 @@ func routeDiff(existRoutes []netlink.Route, cidrs, joinCIDR []string, gateway st
if !found {
toDel = append(toDel, route)
}
conflict := false
for _, vr := range existVlanRoutes {
if vr.Dst.String() == route.Dst.String() {
// route conflict
conflict = true
break
}
}
if conflict {
toDel = append(toDel, route)
}
}
if len(toDel) > 0 {
klog.Infof("route to del %v", toDel)
Expand All @@ -305,6 +347,18 @@ func routeDiff(existRoutes []netlink.Route, cidrs, joinCIDR []string, gateway st
}

found := false
existVlanDirectRoute := false
for _, vr := range existVlanRoutes {
if vr.Dst.String() == c {
// vlan route exists means ovs bridge has ip to be accessed from outside
// so no need to change route for this cidr
existVlanDirectRoute = true
break
}
}
if existVlanDirectRoute {
continue
}
for _, r := range existRoutes {
if r.Dst == nil || r.Dst.String() != c {
continue
Expand Down

0 comments on commit ba1a285

Please sign in to comment.