Skip to content

Commit

Permalink
feat: support VLAN subnet in VPC
Browse files Browse the repository at this point in the history
  • Loading branch information
fanriming committed Sep 15, 2021
1 parent 4c3e428 commit 1e766f9
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 8 deletions.
9 changes: 5 additions & 4 deletions pkg/controller/subnet.go
Original file line number Diff line number Diff line change
Expand Up @@ -569,20 +569,21 @@ func (c *Controller) handleAddOrUpdateSubnet(key string) error {
return err
}

needRouter := subnet.Spec.Vlan == "" || subnet.Spec.Vpc != util.DefaultVpc
if !exist {
subnet.Status.EnsureStandardConditions()
// If multiple namespace use same ls name, only first one will success
if err := c.ovnClient.CreateLogicalSwitch(subnet.Name, vpc.Status.Router, subnet.Spec.Protocol, subnet.Spec.CIDRBlock, subnet.Spec.Gateway, subnet.Spec.Vlan != ""); err != nil {
if err := c.ovnClient.CreateLogicalSwitch(subnet.Name, vpc.Status.Router, subnet.Spec.Protocol, subnet.Spec.CIDRBlock, subnet.Spec.Gateway, subnet.Spec.ExcludeIps, needRouter); err != nil {
c.patchSubnetStatus(subnet, "CreateLogicalSwitchFailed", err.Error())
return err
}
} else {
// logical switch exists, only update other_config
if err := c.ovnClient.SetLogicalSwitchConfig(subnet.Name, vpc.Status.Router, subnet.Spec.Protocol, subnet.Spec.CIDRBlock, subnet.Spec.Gateway, subnet.Spec.Vlan != ""); err != nil {
if err := c.ovnClient.SetLogicalSwitchConfig(subnet.Name, vpc.Status.Router, subnet.Spec.Protocol, subnet.Spec.CIDRBlock, subnet.Spec.Gateway, subnet.Spec.ExcludeIps, needRouter); err != nil {
c.patchSubnetStatus(subnet, "SetLogicalSwitchConfigFailed", err.Error())
return err
}
if subnet.Spec.Vlan != "" {
if !needRouter {
if err := c.ovnClient.RemoveRouterPort(subnet.Name, vpc.Status.Router); err != nil {
klog.Errorf("failed to remove router port from %s, %v", subnet.Name, err)
return err
Expand Down Expand Up @@ -843,7 +844,7 @@ func (c *Controller) reconcileGateway(subnet *kubeovnv1.Subnet) error {
return err
}

if subnet.Spec.Vlan != "" {
if subnet.Spec.Vlan != "" && subnet.Spec.Vpc == util.DefaultVpc {
for _, pod := range pods {
if pod.Annotations[util.LogicalSwitchAnnotation] == subnet.Name && pod.Annotations[util.IpAddressAnnotation] != "" {
if err := c.deleteStaticRoute(pod.Annotations[util.IpAddressAnnotation], c.config.ClusterRouter, subnet); err != nil {
Expand Down
26 changes: 26 additions & 0 deletions pkg/daemon/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,13 @@ func ovsInitProviderNetwork(provider, nic string) (int, error) {
return 0, errMsg
}

// init provider chassis mac
if err := initProviderChassisMac(provider); err != nil {
errMsg := fmt.Errorf("failed to init chassis mac for provider %s, %v", provider, err)
klog.Error(errMsg)
return 0, errMsg
}

// add host nic to the external bridge
mtu, err := configProviderNic(nic, brName)
if err != nil {
Expand Down Expand Up @@ -154,6 +161,25 @@ func ovsCleanProviderNetwork(provider string) error {
}
}

if output, err = ovs.Exec(ovs.IfExists, "get", "open", ".", "external-ids:ovn-chassis-mac-mappings"); err != nil {
return fmt.Errorf("failed to get ovn-chassis-mac-mappings, %v: %q", err, output)
}
macMappings := strings.Split(output, ",")
for _, macMap := range macMappings {
if len(macMap) == len(provider)+18 && strings.HasPrefix(macMap, provider) {
macMappings = util.RemoveString(macMappings, macMap)
break
}
}
if len(macMappings) == 0 {
output, err = ovs.Exec(ovs.IfExists, "remove", "open", ".", "external-ids", "ovn-chassis-mac-mappings")
} else {
output, err = ovs.Exec("set", "open", ".", "external-ids:ovn-chassis-mac-mappings="+strings.Join(macMappings, ","))
}
if err != nil {
return fmt.Errorf("failed to set ovn-chassis-mac-mappings, %v: %q", err, output)
}

// get host nic
if output, err = ovs.Exec("list-ports", brName); err != nil {
return fmt.Errorf("failed to list ports of OVS bridge %s, %v: %q", brName, err, output)
Expand Down
22 changes: 22 additions & 0 deletions pkg/daemon/ovs.go
Original file line number Diff line number Diff line change
Expand Up @@ -524,6 +524,28 @@ func configExternalBridge(provider, bridge, nic string) error {
return nil
}

func initProviderChassisMac(provider string) error {
output, err := ovs.Exec(ovs.IfExists, "get", "open", ".", "external-ids:ovn-chassis-mac-mappings")
if err != nil {
return fmt.Errorf("failed to get ovn-bridge-mappings, %v", err)
}

for _, macMap := range strings.Split(output, ",") {
if len(macMap) == len(provider)+18 && strings.Contains(output, provider) {
return nil
}
}

macMappings := fmt.Sprintf("%s:%s", provider, util.GenerateMac())
if output != "" {
macMappings = fmt.Sprintf("%s,%s", output, macMappings)
}
if output, err = ovs.Exec("set", "open", ".", "external-ids:ovn-chassis-mac-mappings="+macMappings); err != nil {
return fmt.Errorf("failed to set ovn-chassis-mac-mappings, %v: %q", err, output)
}
return nil
}

// Add host nic to external bridge
// Mac address, MTU, IP addresses & routes will be copied/transferred to the external bridge
func configProviderNic(nicName, brName string) (int, error) {
Expand Down
8 changes: 4 additions & 4 deletions pkg/ovs/ovn-nbctl.go
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ func (c Client) ListPodLogicalSwitchPorts(pod, namespace string) ([]string, erro
return result, nil
}

func (c Client) SetLogicalSwitchConfig(ls, lr, protocol, subnet, gateway string, underlay bool) error {
func (c Client) SetLogicalSwitchConfig(ls, lr, protocol, subnet, gateway string, excludeIps []string, needRouter bool) error {
var err error
cidrBlocks := strings.Split(subnet, ",")
mask := strings.Split(cidrBlocks[0], "/")[1]
Expand All @@ -256,7 +256,7 @@ func (c Client) SetLogicalSwitchConfig(ls, lr, protocol, subnet, gateway string,

cmd = []string{MayExist, "ls-add", ls}
}
if !underlay {
if needRouter {
cmd = append(cmd, []string{"--",
"set", "logical_router_port", fmt.Sprintf("%s-%s", lr, ls), fmt.Sprintf("networks=%s", networks)}...)
}
Expand All @@ -271,7 +271,7 @@ func (c Client) SetLogicalSwitchConfig(ls, lr, protocol, subnet, gateway string,
}

// CreateLogicalSwitch create logical switch in ovn, connect it to router and apply tcp/udp lb rules
func (c Client) CreateLogicalSwitch(ls, lr, protocol, subnet, gateway string, underlay bool) error {
func (c Client) CreateLogicalSwitch(ls, lr, protocol, subnet, gateway string, excludeIps []string, needRouter bool) error {
var err error
switch protocol {
case kubeovnv1.ProtocolIPv4:
Expand All @@ -293,7 +293,7 @@ func (c Client) CreateLogicalSwitch(ls, lr, protocol, subnet, gateway string, un

ip := util.GetIpAddrWithMask(gateway, subnet)
mac := util.GenerateMac()
if !underlay {
if needRouter {
if err := c.createRouterPort(ls, lr, ip, mac); err != nil {
klog.Errorf("failed to connect switch %s to router, %v", ls, err)
return err
Expand Down

0 comments on commit 1e766f9

Please sign in to comment.