This repository has been archived by the owner on Jun 20, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 672
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
The change makes "weave expose" to call the "/expose" HTTP endpoint implemented in router which exposes the bridge. Such architectural change required as we need to know whether NPC is enabled when exposing the bridge and weaver knows this fact the best. Unfortunately, this change makes impossible to "weave expose" when weaver is not running.
- Loading branch information
Showing
12 changed files
with
155 additions
and
134 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package api | ||
|
||
import ( | ||
"fmt" | ||
"net" | ||
) | ||
|
||
// Expose calls the router to assign the given IP addr to the weave bridge. | ||
func (client *Client) Expose(ipAddr *net.IPNet) error { | ||
_, err := client.httpVerb("POST", fmt.Sprintf("/expose/%s", ipAddr), nil) | ||
return err | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
package net | ||
|
||
import ( | ||
"net" | ||
"syscall" | ||
|
||
"github.com/coreos/go-iptables/iptables" | ||
"github.com/j-keck/arping" | ||
"github.com/pkg/errors" | ||
"github.com/vishvananda/netlink" | ||
) | ||
|
||
// Expose makes the network accessible from a host by assigning a given IP address | ||
// to the weave bridge. | ||
// | ||
// List of params: | ||
// * "bridgeName" - a name of the weave bridge. | ||
// * "ipAddr" - IP addr to be assigned to the bridge. | ||
// * "removeDefaultRoute" - whether to remove a default route installed by the kernel (used only in the AWSVPC mode). | ||
// * "npc" - whether is Weave NPC running. | ||
func Expose(bridgeName string, ipAddr *net.IPNet, removeDefaultRoute, npc bool) error { | ||
if err := addBridgeIPAddr(bridgeName, ipAddr, removeDefaultRoute); err != nil { | ||
return errors.Wrap(err, "addBridgeIPAddr") | ||
} | ||
|
||
if err := exposeNAT(ipAddr); err != nil { | ||
return errors.Wrap(err, "exposeNAT") | ||
} | ||
|
||
if !npc { | ||
// TODO comment why not in npc mode && add filter rules and docs | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func addBridgeIPAddr(bridgeName string, addr *net.IPNet, removeDefaultRoute bool) error { | ||
link, err := netlink.LinkByName(bridgeName) | ||
if err != nil { | ||
return errors.Wrapf(err, "addBridgeIPAddr finding bridge %q", bridgeName) | ||
} | ||
err = netlink.AddrAdd(link, &netlink.Addr{IPNet: addr}) | ||
// The IP addr might have been already set by a concurrent request, just ignore then | ||
if err != nil && err != syscall.Errno(syscall.EEXIST) { | ||
return errors.Wrapf(err, "adding address %v to %q", addr, bridgeName) | ||
} | ||
|
||
// Sending multiple ARP REQUESTs in the case of EEXIST above does not hurt | ||
arping.GratuitousArpOverIfaceByName(addr.IP, bridgeName) | ||
|
||
// Remove a default route installed by the kernel. Required by the AWSVPC mode. | ||
if removeDefaultRoute { | ||
routeFilter := &netlink.Route{ | ||
LinkIndex: link.Attrs().Index, | ||
Dst: &net.IPNet{IP: addr.IP.Mask(addr.Mask), Mask: addr.Mask}, | ||
Protocol: 2, // RTPROT_KERNEL | ||
} | ||
filterMask := netlink.RT_FILTER_OIF | netlink.RT_FILTER_DST | netlink.RT_FILTER_PROTOCOL | ||
routes, err := netlink.RouteListFiltered(netlink.FAMILY_V4, routeFilter, filterMask) | ||
if err != nil { | ||
return errors.Wrapf(err, "failed to get route list for bridge %q", bridgeName) | ||
} | ||
for _, r := range routes { | ||
err = netlink.RouteDel(&r) | ||
// Again, there might be a concurrent request for removing routes | ||
if err != nil && err != syscall.Errno(syscall.ESRCH) { | ||
return errors.Wrapf(err, "failed to delete default route %+v", r) | ||
} | ||
} | ||
} | ||
return nil | ||
} | ||
|
||
func exposeNAT(ipnet *net.IPNet) error { | ||
ipt, err := iptables.New() | ||
if err != nil { | ||
return err | ||
} | ||
cidr := ipnet.String() | ||
|
||
if err := addNatRule(ipt, "-s", cidr, "-d", "224.0.0.0/4", "-j", "RETURN"); err != nil { | ||
return err | ||
} | ||
if err := addNatRule(ipt, "-d", cidr, "!", "-s", cidr, "-j", "MASQUERADE"); err != nil { | ||
return err | ||
} | ||
if err := addNatRule(ipt, "-s", cidr, "!", "-d", cidr, "-j", "MASQUERADE"); err != nil { | ||
return err | ||
} | ||
return nil | ||
} | ||
|
||
func addNatRule(ipt *iptables.IPTables, rulespec ...string) error { | ||
// Loop until we get an exit code other than "temporarily unavailable" | ||
for { | ||
if err := ipt.AppendUnique("nat", "WEAVE", rulespec...); err != nil { | ||
if ierr, ok := err.(*iptables.Error); ok { | ||
if status, ok := ierr.ExitError.Sys().(syscall.WaitStatus); ok { | ||
// (magic exit code 4 found in iptables source code; undocumented) | ||
if status.ExitStatus() == 4 { | ||
continue | ||
} | ||
} | ||
} | ||
return err | ||
} | ||
return nil | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.