Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sdn: handle offset>0 fragments when validating service traffic #13162

Merged
merged 1 commit into from
Mar 8, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 31 additions & 18 deletions pkg/sdn/plugin/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,10 @@ func (plugin *OsdnNode) SetupSDN() (bool, error) {
if err != nil {
return false, err
}
err = plugin.ovs.SetFrags("nx-match")
if err != nil {
return false, err
}
_ = plugin.ovs.DeletePort(VXLAN)
_, err = plugin.ovs.AddPort(VXLAN, 1, "type=vxlan", `options:remote_ip="flow"`, `options:key="flow"`)
if err != nil {
Expand Down Expand Up @@ -457,35 +461,44 @@ func (plugin *OsdnNode) AddServiceRules(service *kapi.Service, netID uint32) {
glog.V(5).Infof("AddServiceRules for %v", service)

otx := plugin.ovs.NewTransaction()
action := fmt.Sprintf(", priority=100, actions=load:%d->NXM_NX_REG1[], load:2->NXM_NX_REG2[], goto_table:80", netID)

// Add blanket rule allowing subsequent IP fragments
otx.AddFlow(generateBaseServiceRule(service.Spec.ClusterIP) + ", ip_frag=later" + action)

for _, port := range service.Spec.Ports {
otx.AddFlow(generateAddServiceRule(netID, service.Spec.ClusterIP, port.Protocol, int(port.Port)))
if err := otx.EndTransaction(); err != nil {
glog.Errorf("Error adding OVS flows for service %v, netid %d: %v", service, netID, err)
baseRule, err := generateBaseAddServiceRule(service.Spec.ClusterIP, port.Protocol, int(port.Port))
if err != nil {
glog.Errorf("Error creating OVS flow for service %v, netid %d: %v", service, netID, err)
}
otx.AddFlow(baseRule + action)
}

if err := otx.EndTransaction(); err != nil {
glog.Errorf("Error adding OVS flows for service %v, netid %d: %v", service, netID, err)
}
}

func (plugin *OsdnNode) DeleteServiceRules(service *kapi.Service) {
glog.V(5).Infof("DeleteServiceRules for %v", service)

otx := plugin.ovs.NewTransaction()
for _, port := range service.Spec.Ports {
otx.DeleteFlows(generateDeleteServiceRule(service.Spec.ClusterIP, port.Protocol, int(port.Port)))
if err := otx.EndTransaction(); err != nil {
glog.Errorf("Error deleting OVS flows for service %v: %v", service, err)
}
}
otx.DeleteFlows(generateBaseServiceRule(service.Spec.ClusterIP))
otx.EndTransaction()
}

func generateBaseServiceRule(IP string, protocol kapi.Protocol, port int) string {
return fmt.Sprintf("table=60, %s, nw_dst=%s, tp_dst=%d", strings.ToLower(string(protocol)), IP, port)
func generateBaseServiceRule(IP string) string {
return fmt.Sprintf("table=60, ip, nw_dst=%s", IP)
}

func generateAddServiceRule(netID uint32, IP string, protocol kapi.Protocol, port int) string {
baseRule := generateBaseServiceRule(IP, protocol, port)
return fmt.Sprintf("%s, priority=100, actions=load:%d->NXM_NX_REG1[], load:2->NXM_NX_REG2[], goto_table:80", baseRule, netID)
}

func generateDeleteServiceRule(IP string, protocol kapi.Protocol, port int) string {
return generateBaseServiceRule(IP, protocol, port)
func generateBaseAddServiceRule(IP string, protocol kapi.Protocol, port int) (string, error) {
var dst string
if protocol == kapi.ProtocolUDP {
dst = fmt.Sprintf(", udp, udp_dst=%d", port)
} else if protocol == kapi.ProtocolTCP {
dst = fmt.Sprintf(", tcp, tcp_dst=%d", port)
} else {
return "", fmt.Errorf("unhandled protocol %v", protocol)
}
return generateBaseServiceRule(IP) + dst, nil
}
5 changes: 5 additions & 0 deletions pkg/util/ovs/ovs.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,11 @@ func (ovsif *Interface) DeletePort(port string) error {
return err
}

func (ovsif *Interface) SetFrags(mode string) error {
_, err := ovsif.exec(OVS_OFCTL, "set-frags", ovsif.bridge, mode)
return err
}

type Transaction struct {
ovsif *Interface
err error
Expand Down