Skip to content

Instantly share code, notes, and snippets.

@astoycos
Created March 22, 2022 13:58
Show Gist options
  • Select an option

  • Save astoycos/604946cf62cf71e1abaccf88f7bbe5a7 to your computer and use it in GitHub Desktop.

Select an option

Save astoycos/604946cf62cf71e1abaccf88f7bbe5a7 to your computer and use it in GitHub Desktop.
Tmp-Sub-route-controller
type SubRouteKey struct {
dst string
gws stringset.Interface
}
func (kp *SyncHandler) listExistingRoutes() (map[SubRouteKey]netlink.Route, error) {
currentRoutes := map[SubRouteKey]netlink.Route{}
currentRouteList, err := kp.netLink.RouteList(kp.vxlanDevice.link, syscall.AF_INET)
if err != nil {
return nil, errors.Wrapf(err, "error retrieving routes for link %s", VxLANIface)
}
for _, route := range currentRouteList {
gws := stringset.NewSynchronized()
for _, nextHop := range route.MultiPath {
gws.Add(nextHop.Gw.String())
}
key := SubRouteKey{dst: route.Dst.String(), gws: gws}
currentRoutes[key] = route
}
return currentRoutes, nil
}
// buildDesiredRoutes will make all routes needed for intra cluster communication within
// submariner. Specifically it will route traffic originating on a worker node, destined
// for another cluster, to an active GW
func (kp *SyncHandler) buildDesiredRoutes() (map[SubRouteKey]netlink.Route, error) {
desiredRoutes := map[SubRouteKey]netlink.Route{}
nextHops := []*netlink.NexthopInfo{}
for _, gw := range kp.gwVTEPs.Elements() {
nextHops = append(nextHops, &netlink.NexthopInfo{
Gw: net.ParseIP(gw),
LinkIndex: kp.vxlanDevice.link.Attrs().Index,
})
}
for _, remoteSubnet := range kp.remoteSubnets.Elements() {
key := SubRouteKey{dst: remoteSubnet, gws: kp.gwVTEPs}
_, dst, err := net.ParseCIDR(remoteSubnet)
if err != nil {
return nil, errors.Errorf("Error parsing cidr block %s: %v", remoteSubnet, err)
}
route := netlink.Route{
Dst: dst,
MultiPath: nextHops,
Scope: unix.RT_SCOPE_UNIVERSE,
LinkIndex: kp.vxlanDevice.link.Attrs().Index,
Protocol: 4,
}
desiredRoutes[key] = route
}
return desiredRoutes, nil
}
// Reconcile the routes based on the GWIPs installed on this device using rtnetlink.
func (kp *SyncHandler) reconcileIntraClusterRoutes() error {
currentRouteList, err := kp.listExistingRoutes()
if err != nil {
return errors.Wrapf(err, "error retrieving routes for link %s", VxLANIface)
}
if kp.isGatewayNode {
klog.V(log.DEBUG).Infof("Node is a GW, delete all intra cluster Routes on %v", VxLANIface)
for _, route := range currentRouteList {
klog.V(log.DEBUG).Infof("Node is a GW Removing route %s", route.String())
if err = kp.netLink.RouteDel(&route); err != nil {
klog.Errorf("Error removing route %s: %v", route, err)
}
}
return nil
}
klog.V(log.DEBUG).Infof("Reconciling existing routes %v to gws %v on worker node", currentRouteList, kp.gwVTEPs.Elements())
desiredRouteList, err := kp.buildDesiredRoutes()
if err != nil {
return errors.Wrapf(err, "error retrieving desired routes for link %s", VxLANIface)
}
for key, route := range currentRouteList {
// route exists and is up to date keep it
if _, ok := desiredRouteList[key]; ok {
delete(desiredRouteList, key)
continue
}
// don't remove auto-generated route for vxlan-submariner
if kp.vxlanDevice != nil && route.Src.Equal(kp.vxlanDevice.link.SrcAddr) {
klog.V(log.DEBUG).Infof("Skipping removal of autogenerated route: %s", route)
continue
}
// if not in list delete it
klog.V(log.DEBUG).Infof("Removing stale route %s", route)
if err = kp.netLink.RouteDel(&route); err != nil {
klog.Errorf("Error removing route %s: %v", route, err)
}
}
// Let's now add the routes that are missing.
for _, route := range desiredRouteList {
// if in desiredRoute list add it.
klog.V(log.DEBUG).Infof("Adding new route %s", route)
err = kp.netLink.RouteAdd(&route)
if err != nil {
klog.Errorf("Error adding route %s: %v", route, err)
}
}
return nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment