Skip to content

Commit

Permalink
Merge pull request #945 from stgraber/ovn
Browse files Browse the repository at this point in the history
Port more functions to libovsdb
  • Loading branch information
hallyn authored Jun 18, 2024
2 parents 1351bb0 + f826ad6 commit b07cb7d
Show file tree
Hide file tree
Showing 2 changed files with 122 additions and 59 deletions.
12 changes: 6 additions & 6 deletions internal/server/network/driver_ovn.go
Original file line number Diff line number Diff line change
Expand Up @@ -2132,7 +2132,7 @@ func (n *ovn) setup(update bool) error {
})
}

err = n.state.OVNNB.LogicalSwitchPortLinkRouter(n.getExtSwitchRouterPortName(), n.getRouterExtPortName())
err = n.state.OVNNB.UpdateLogicalSwitchPortLinkRouter(context.TODO(), n.getExtSwitchRouterPortName(), n.getRouterExtPortName())
if err != nil {
return fmt.Errorf("Failed linking external router port to external switch port: %w", err)
}
Expand All @@ -2149,7 +2149,7 @@ func (n *ovn) setup(update bool) error {
})
}

err = n.state.OVNNB.LogicalSwitchPortLinkProviderNetwork(n.getExtSwitchProviderPortName(), uplinkNet.extSwitchProviderName)
err = n.state.OVNNB.UpdateLogicalSwitchPortLinkProviderNetwork(context.TODO(), n.getExtSwitchProviderPortName(), uplinkNet.extSwitchProviderName)
if err != nil {
return fmt.Errorf("Failed linking external switch provider port to external provider network: %w", err)
}
Expand Down Expand Up @@ -2483,7 +2483,7 @@ func (n *ovn) setup(update bool) error {
})
}

err = n.state.OVNNB.LogicalSwitchPortLinkRouter(n.getIntSwitchRouterPortName(), n.getRouterIntPortName())
err = n.state.OVNNB.UpdateLogicalSwitchPortLinkRouter(context.TODO(), n.getIntSwitchRouterPortName(), n.getRouterIntPortName())
if err != nil {
return fmt.Errorf("Failed linking internal router port to internal switch port: %w", err)
}
Expand Down Expand Up @@ -3547,7 +3547,7 @@ func (n *ovn) InstanceDevicePortStart(opts *OVNInstanceNICSetupOpts, securityACL
// If the sticky IP isn't statically reserved, lets check its not used dynamically
// on any active port.
if !n.hasDHCPv4Reservation(dhcpReservations, dhcpV4StickyIP) {
existingPortIPs, err := n.state.OVNNB.LogicalSwitchIPs(n.getIntSwitchName())
existingPortIPs, err := n.state.OVNNB.GetLogicalSwitchIPs(context.TODO(), n.getIntSwitchName())
if err != nil {
return "", nil, fmt.Errorf("Failed getting existing switch port IPs: %w", err)
}
Expand Down Expand Up @@ -4093,7 +4093,7 @@ func (n *ovn) InstanceDevicePortStop(ovsExternalOVNPort networkOVN.OVNSwitchPort
}

// Get DNS records.
dnsUUID, _, dnsIPs, err := n.state.OVNNB.LogicalSwitchPortGetDNS(instancePortName)
dnsUUID, _, dnsIPs, err := n.state.OVNNB.GetLogicalSwitchPortDNS(context.TODO(), instancePortName)
if err != nil {
return err
}
Expand Down Expand Up @@ -4190,7 +4190,7 @@ func (n *ovn) InstanceDevicePortRemove(instanceUUID string, deviceName string, d
defer revert.Fail()

// Get DNS records.
dnsUUID, _, _, err := n.state.OVNNB.LogicalSwitchPortGetDNS(instancePortName)
dnsUUID, _, _, err := n.state.OVNNB.GetLogicalSwitchPortDNS(context.TODO(), instancePortName)
if err != nil {
return err
}
Expand Down
169 changes: 116 additions & 53 deletions internal/server/network/ovn/ovn_nb_actions.go
Original file line number Diff line number Diff line change
Expand Up @@ -1491,34 +1491,42 @@ func (o *NB) GetLogicalSwitchPorts(ctx context.Context, switchName OVNSwitch) (m
return ports, nil
}

// LogicalSwitchIPs returns a list of IPs associated to each port connected to switch.
func (o *NB) LogicalSwitchIPs(switchName OVNSwitch) (map[OVNSwitchPort][]net.IP, error) {
output, err := o.nbctl("--format=csv", "--no-headings", "--data=bare", "--colum=name,addresses,dynamic_addresses", "find", "logical_switch_port",
fmt.Sprintf("external_ids:%s=%s", ovnExtIDIncusSwitch, switchName),
)
// GetLogicalSwitchIPs returns a list of IPs associated to each port connected to switch.
func (o *NB) GetLogicalSwitchIPs(ctx context.Context, switchName OVNSwitch) (map[OVNSwitchPort][]net.IP, error) {
lsps := []ovnNB.LogicalSwitchPort{}

err := o.client.WhereCache(func(lsp *ovnNB.LogicalSwitchPort) bool {
return lsp.ExternalIDs != nil && lsp.ExternalIDs[ovnExtIDIncusSwitch] == string(switchName)
}).List(ctx, &lsps)
if err != nil {
return nil, err
}

lines := util.SplitNTrimSpace(strings.TrimSpace(output), "\n", -1, true)
portIPs := make(map[OVNSwitchPort][]net.IP, len(lines))

for _, line := range lines {
fields := util.SplitNTrimSpace(line, ",", -1, true)
portName := OVNSwitchPort(fields[0])
portIPs := make(map[OVNSwitchPort][]net.IP, len(lsps))
for _, lsp := range lsps {
var ips []net.IP

// Parse all IPs mentioned in addresses and dynamic_addresses fields.
for i := 1; i < len(fields); i++ {
for _, address := range util.SplitNTrimSpace(fields[i], " ", -1, true) {
ip := net.ParseIP(address)
// Extract all addresses from the Addresses field.
for _, address := range lsp.Addresses {
for _, entry := range util.SplitNTrimSpace(address, " ", -1, true) {
ip := net.ParseIP(entry)
if ip != nil {
ips = append(ips, ip)
}
}
}

// Extract all addresses from the DynamicAddresses field.
if lsp.DynamicAddresses != nil {
for _, entry := range util.SplitNTrimSpace(*lsp.DynamicAddresses, " ", -1, true) {
ip := net.ParseIP(entry)
if ip != nil {
ips = append(ips, ip)
}
}
}

portIPs[portName] = ips
portIPs[OVNSwitchPort(lsp.Name)] = ips
}

return portIPs, nil
Expand Down Expand Up @@ -1846,38 +1854,40 @@ func (o *NB) LogicalSwitchPortSetDNS(switchName OVNSwitch, portName OVNSwitchPor
return OVNDNSUUID(dnsUUID), nil
}

// LogicalSwitchPortGetDNS returns the logical switch port DNS info (UUID, name and IPs).
func (o *NB) LogicalSwitchPortGetDNS(portName OVNSwitchPort) (OVNDNSUUID, string, []net.IP, error) {
// Get UUID and DNS IPs for a switch port in the format: "<DNS UUID>,<DNS NAME>=<IP> <IP>"
output, err := o.nbctl("--format=csv", "--no-headings", "--data=bare", "--colum=_uuid,records", "find", "dns",
fmt.Sprintf("external_ids:%s=%s", ovnExtIDIncusSwitchPort, portName),
)
// GetLogicalSwitchPortDNS returns the logical switch port DNS info (UUID, name and IPs).
func (o *NB) GetLogicalSwitchPortDNS(ctx context.Context, portName OVNSwitchPort) (OVNDNSUUID, string, []net.IP, error) {
dnsRecords := []ovnNB.DNS{}

err := o.client.WhereCache(func(dnsRecord *ovnNB.DNS) bool {
return dnsRecord.ExternalIDs != nil && dnsRecord.ExternalIDs[ovnExtIDIncusSwitchPort] == string(portName)
}).List(ctx, &dnsRecords)
if err != nil {
return "", "", nil, err
}

parts := strings.Split(strings.TrimSpace(output), ",")
dnsUUID := strings.TrimSpace(parts[0])
if len(dnsRecords) != 1 {
return "", "", nil, nil
}

if len(dnsRecords[0].Records) > 1 {
return "", "", nil, fmt.Errorf("More than one DNS record found for logical switch port")
}

var dnsName string
var ips []net.IP
var dnsName string

// Try and parse the DNS name and IPs.
if len(parts) > 1 {
dnsParts := strings.SplitN(strings.TrimSpace(parts[1]), "=", 2)
if len(dnsParts) == 2 {
dnsName = strings.TrimSpace(dnsParts[0])
ipParts := strings.Split(dnsParts[1], " ")
for _, ipPart := range ipParts {
ip := net.ParseIP(strings.TrimSpace(ipPart))
if ip != nil {
ips = append(ips, ip)
}
for key, value := range dnsRecords[0].Records {
dnsName = key

for _, ipPart := range strings.Split(value, " ") {
ip := net.ParseIP(strings.TrimSpace(ipPart))
if ip != nil {
ips = append(ips, ip)
}
}
}

return OVNDNSUUID(dnsUUID), dnsName, ips, nil
return OVNDNSUUID(dnsRecords[0].UUID), dnsName, ips, nil
}

// logicalSwitchPortDeleteDNSAppendArgs adds the command arguments to remove DNS records from a switch port.
Expand Down Expand Up @@ -2006,29 +2016,82 @@ func (o *NB) LogicalSwitchPortCleanup(portName OVNSwitchPort, switchName OVNSwit
return nil
}

// LogicalSwitchPortLinkRouter links a logical switch port to a logical router port.
func (o *NB) LogicalSwitchPortLinkRouter(switchPortName OVNSwitchPort, routerPortName OVNRouterPort) error {
// Connect logical router port to switch.
_, err := o.nbctl(
"lsp-set-type", string(switchPortName), "router", "--",
"lsp-set-addresses", string(switchPortName), "router", "--",
"lsp-set-options", string(switchPortName), fmt.Sprintf("nat-addresses=%s", "router"), fmt.Sprintf("router-port=%s", string(routerPortName)),
)
// UpdateLogicalSwitchPortLinkRouter links a logical switch port to a logical router port.
func (o *NB) UpdateLogicalSwitchPortLinkRouter(ctx context.Context, switchPortName OVNSwitchPort, routerPortName OVNRouterPort) error {
// Get the logical switch port.
lsp := ovnNB.LogicalSwitchPort{
Name: string(switchPortName),
}

err := o.get(ctx, &lsp)
if err != nil {
return err
}

// Update the fields.
lsp.Type = "router"
lsp.Addresses = []string{"router"}
if lsp.Options == nil {
lsp.Options = map[string]string{}
}

lsp.Options["nat-addresses"] = "router"
lsp.Options["router-port"] = string(routerPortName)

// Update the record.
operations, err := o.client.Where(&lsp).Update(&lsp)
if err != nil {
return err
}

// Apply the changes.
resp, err := o.client.Transact(ctx, operations...)
if err != nil {
return err
}

_, err = ovsdb.CheckOperationResults(resp, operations)
if err != nil {
return err
}

return nil
}

// LogicalSwitchPortLinkProviderNetwork links a logical switch port to a provider network.
func (o *NB) LogicalSwitchPortLinkProviderNetwork(switchPortName OVNSwitchPort, extNetworkName string) error {
// Forward any unknown MAC frames down this port.
_, err := o.nbctl(
"lsp-set-addresses", string(switchPortName), "unknown", "--",
"lsp-set-type", string(switchPortName), "localnet", "--",
"lsp-set-options", string(switchPortName), fmt.Sprintf("network_name=%s", extNetworkName),
)
// UpdateLogicalSwitchPortLinkProviderNetwork links a logical switch port to a provider network.
func (o *NB) UpdateLogicalSwitchPortLinkProviderNetwork(ctx context.Context, switchPortName OVNSwitchPort, extNetworkName string) error {
// Get the logical switch port.
lsp := ovnNB.LogicalSwitchPort{
Name: string(switchPortName),
}

err := o.get(ctx, &lsp)
if err != nil {
return err
}

// Update the fields.
lsp.Type = "localnet"
lsp.Addresses = []string{"unknown"}
if lsp.Options == nil {
lsp.Options = map[string]string{}
}

lsp.Options["network_name"] = extNetworkName

// Update the record.
operations, err := o.client.Where(&lsp).Update(&lsp)
if err != nil {
return err
}

// Apply the changes.
resp, err := o.client.Transact(ctx, operations...)
if err != nil {
return err
}

_, err = ovsdb.CheckOperationResults(resp, operations)
if err != nil {
return err
}
Expand Down

0 comments on commit b07cb7d

Please sign in to comment.