full diff: https://github.com/docker/libnetwork/compare/83d30db53600b9c084d35fb1d560f97f8b34ab24...09cdcc8c0eab3946c2d70e8f6225b05baf1e90d1
changes included:
- docker/libnetwork#2416 Fix hardcoded AF_INET for IPv6 address handling
- docker/libnetwork#2411 Macvlan network handles netlabel.Internal wrong
- fixes docker/libnetwork#2410 Macvlan network handles netlabel.Internal wrong
- docker/libnetwork#2414 Allow network with --config-from to be --internal
- fixes docker/libnetwork#2413 Network with --config-from does not honor --internal
- docker/libnetwork#2351 Use fewer modprobes
- relates to moby/moby#38930 Use fewer modprobes
- docker/libnetwork#2415 Support dockerd and system restarts for ipvlan and macvlan networks
- carry of docker/libnetwork#2295 phantom ip/mac vlan network after a powercycle
- fixes docker/libnetwork#1743 Phantom docker network
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 6f234db9fef23c591d8376f96db062e7107b658f)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
| ... | ... |
@@ -3,7 +3,7 @@ |
| 3 | 3 |
# LIBNETWORK_COMMIT is used to build the docker-userland-proxy binary. When |
| 4 | 4 |
# updating the binary version, consider updating github.com/docker/libnetwork |
| 5 | 5 |
# in vendor.conf accordingly |
| 6 |
-LIBNETWORK_COMMIT=83d30db53600b9c084d35fb1d560f97f8b34ab24 |
|
| 6 |
+LIBNETWORK_COMMIT=09cdcc8c0eab3946c2d70e8f6225b05baf1e90d1 |
|
| 7 | 7 |
|
| 8 | 8 |
install_proxy() {
|
| 9 | 9 |
case "$1" in |
| ... | ... |
@@ -39,7 +39,7 @@ github.com/gofrs/flock 7f43ea2e6a643ad441fc12d0ecc0 |
| 39 | 39 |
# libnetwork |
| 40 | 40 |
|
| 41 | 41 |
# When updating, also update LIBNETWORK_COMMIT in hack/dockerfile/install/proxy.installer accordingly |
| 42 |
-github.com/docker/libnetwork 83d30db53600b9c084d35fb1d560f97f8b34ab24 |
|
| 42 |
+github.com/docker/libnetwork 09cdcc8c0eab3946c2d70e8f6225b05baf1e90d1 |
|
| 43 | 43 |
github.com/docker/go-events 9461782956ad83b30282bf90e31fa6a70c255ba9 |
| 44 | 44 |
github.com/armon/go-radix e39d623f12e8e41c7b5529e9a9dd67a1e2261f80 |
| 45 | 45 |
github.com/armon/go-metrics eb0af217e5e9747e41dd5303755356b62d28e3ec |
| ... | ... |
@@ -706,9 +706,10 @@ const overlayDSROptionString = "dsr" |
| 706 | 706 |
// are network specific and modeled in a generic way. |
| 707 | 707 |
func (c *controller) NewNetwork(networkType, name string, id string, options ...NetworkOption) (Network, error) {
|
| 708 | 708 |
var ( |
| 709 |
- cap *driverapi.Capability |
|
| 710 |
- err error |
|
| 711 |
- t *network |
|
| 709 |
+ cap *driverapi.Capability |
|
| 710 |
+ err error |
|
| 711 |
+ t *network |
|
| 712 |
+ skipCfgEpCount bool |
|
| 712 | 713 |
) |
| 713 | 714 |
|
| 714 | 715 |
if id != "" {
|
| ... | ... |
@@ -801,8 +802,9 @@ func (c *controller) NewNetwork(networkType, name string, id string, options ... |
| 801 | 801 |
if err = t.applyConfigurationTo(network); err != nil {
|
| 802 | 802 |
return nil, types.InternalErrorf("Failed to apply configuration: %v", err)
|
| 803 | 803 |
} |
| 804 |
+ network.generic[netlabel.Internal] = network.internal |
|
| 804 | 805 |
defer func() {
|
| 805 |
- if err == nil {
|
|
| 806 |
+ if err == nil && !skipCfgEpCount {
|
|
| 806 | 807 |
if err := t.getEpCnt().IncEndpointCnt(); err != nil {
|
| 807 | 808 |
logrus.Warnf("Failed to update reference count for configuration network %q on creation of network %q: %v",
|
| 808 | 809 |
t.Name(), network.Name(), err) |
| ... | ... |
@@ -823,7 +825,13 @@ func (c *controller) NewNetwork(networkType, name string, id string, options ... |
| 823 | 823 |
|
| 824 | 824 |
err = c.addNetwork(network) |
| 825 | 825 |
if err != nil {
|
| 826 |
- return nil, err |
|
| 826 |
+ if strings.Contains(err.Error(), "restoring existing network") {
|
|
| 827 |
+ // This error can be ignored and set this boolean |
|
| 828 |
+ // value to skip a refcount increment for configOnly networks |
|
| 829 |
+ skipCfgEpCount = true |
|
| 830 |
+ } else {
|
|
| 831 |
+ return nil, err |
|
| 832 |
+ } |
|
| 827 | 833 |
} |
| 828 | 834 |
defer func() {
|
| 829 | 835 |
if err != nil {
|
| ... | ... |
@@ -60,10 +60,14 @@ func (d *driver) CreateNetwork(nid string, option map[string]interface{}, nInfo
|
| 60 | 60 |
// empty parent and --internal are handled the same. Set here to update k/v |
| 61 | 61 |
config.Internal = true |
| 62 | 62 |
} |
| 63 |
- err = d.createNetwork(config) |
|
| 63 |
+ foundExisting, err := d.createNetwork(config) |
|
| 64 | 64 |
if err != nil {
|
| 65 | 65 |
return err |
| 66 | 66 |
} |
| 67 |
+ |
|
| 68 |
+ if foundExisting {
|
|
| 69 |
+ return types.InternalMaskableErrorf("restoring existing network %s", config.ID)
|
|
| 70 |
+ } |
|
| 67 | 71 |
// update persistent db, rollback on fail |
| 68 | 72 |
err = d.storeUpdate(config) |
| 69 | 73 |
if err != nil {
|
| ... | ... |
@@ -76,12 +80,18 @@ func (d *driver) CreateNetwork(nid string, option map[string]interface{}, nInfo
|
| 76 | 76 |
} |
| 77 | 77 |
|
| 78 | 78 |
// createNetwork is used by new network callbacks and persistent network cache |
| 79 |
-func (d *driver) createNetwork(config *configuration) error {
|
|
| 79 |
+func (d *driver) createNetwork(config *configuration) (bool, error) {
|
|
| 80 |
+ foundExisting := false |
|
| 80 | 81 |
networkList := d.getNetworks() |
| 81 | 82 |
for _, nw := range networkList {
|
| 82 | 83 |
if config.Parent == nw.config.Parent {
|
| 83 |
- return fmt.Errorf("network %s is already using parent interface %s",
|
|
| 84 |
- getDummyName(stringid.TruncateID(nw.config.ID)), config.Parent) |
|
| 84 |
+ if config.ID != nw.config.ID {
|
|
| 85 |
+ return false, fmt.Errorf("network %s is already using parent interface %s",
|
|
| 86 |
+ getDummyName(stringid.TruncateID(nw.config.ID)), config.Parent) |
|
| 87 |
+ } |
|
| 88 |
+ logrus.Debugf("Create Network for the same ID %s\n", config.ID)
|
|
| 89 |
+ foundExisting = true |
|
| 90 |
+ break |
|
| 85 | 91 |
} |
| 86 | 92 |
} |
| 87 | 93 |
if !parentExists(config.Parent) {
|
| ... | ... |
@@ -89,9 +99,10 @@ func (d *driver) createNetwork(config *configuration) error {
|
| 89 | 89 |
if config.Internal {
|
| 90 | 90 |
err := createDummyLink(config.Parent, getDummyName(stringid.TruncateID(config.ID))) |
| 91 | 91 |
if err != nil {
|
| 92 |
- return err |
|
| 92 |
+ return false, err |
|
| 93 | 93 |
} |
| 94 | 94 |
config.CreatedSlaveLink = true |
| 95 |
+ |
|
| 95 | 96 |
// notify the user in logs they have limited communications |
| 96 | 97 |
if config.Parent == getDummyName(stringid.TruncateID(config.ID)) {
|
| 97 | 98 |
logrus.Debugf("Empty -o parent= and --internal flags limit communications to other containers inside of network: %s",
|
| ... | ... |
@@ -102,22 +113,24 @@ func (d *driver) createNetwork(config *configuration) error {
|
| 102 | 102 |
// a valid example is 'eth0.10' for a parent iface 'eth0' with a vlan id '10' |
| 103 | 103 |
err := createVlanLink(config.Parent) |
| 104 | 104 |
if err != nil {
|
| 105 |
- return err |
|
| 105 |
+ return false, err |
|
| 106 | 106 |
} |
| 107 | 107 |
// if driver created the networks slave link, record it for future deletion |
| 108 | 108 |
config.CreatedSlaveLink = true |
| 109 | 109 |
} |
| 110 | 110 |
} |
| 111 |
- n := &network{
|
|
| 112 |
- id: config.ID, |
|
| 113 |
- driver: d, |
|
| 114 |
- endpoints: endpointTable{},
|
|
| 115 |
- config: config, |
|
| 111 |
+ if !foundExisting {
|
|
| 112 |
+ n := &network{
|
|
| 113 |
+ id: config.ID, |
|
| 114 |
+ driver: d, |
|
| 115 |
+ endpoints: endpointTable{},
|
|
| 116 |
+ config: config, |
|
| 117 |
+ } |
|
| 118 |
+ // add the network |
|
| 119 |
+ d.addNetwork(n) |
|
| 116 | 120 |
} |
| 117 |
- // add the *network |
|
| 118 |
- d.addNetwork(n) |
|
| 119 | 121 |
|
| 120 |
- return nil |
|
| 122 |
+ return foundExisting, nil |
|
| 121 | 123 |
} |
| 122 | 124 |
|
| 123 | 125 |
// DeleteNetwork the network for the specified driver type |
| ... | ... |
@@ -182,10 +195,12 @@ func parseNetworkOptions(id string, option options.Generic) (*configuration, err |
| 182 | 182 |
} |
| 183 | 183 |
} |
| 184 | 184 |
// setting the parent to "" will trigger an isolated network dummy parent link |
| 185 |
- if _, ok := option[netlabel.Internal]; ok {
|
|
| 186 |
- config.Internal = true |
|
| 187 |
- // empty --parent= and --internal are handled the same. |
|
| 188 |
- config.Parent = "" |
|
| 185 |
+ if val, ok := option[netlabel.Internal]; ok {
|
|
| 186 |
+ if internal, ok := val.(bool); ok && internal {
|
|
| 187 |
+ config.Internal = true |
|
| 188 |
+ // empty --parent= and --internal are handled the same. |
|
| 189 |
+ config.Parent = "" |
|
| 190 |
+ } |
|
| 189 | 191 |
} |
| 190 | 192 |
return config, nil |
| 191 | 193 |
} |
| ... | ... |
@@ -55,7 +55,14 @@ func (d *driver) initStore(option map[string]interface{}) error {
|
| 55 | 55 |
return types.InternalErrorf("ipvlan driver failed to initialize data store: %v", err)
|
| 56 | 56 |
} |
| 57 | 57 |
|
| 58 |
- return d.populateNetworks() |
|
| 58 |
+ err = d.populateNetworks() |
|
| 59 |
+ if err != nil {
|
|
| 60 |
+ return err |
|
| 61 |
+ } |
|
| 62 |
+ err = d.populateEndpoints() |
|
| 63 |
+ if err != nil {
|
|
| 64 |
+ return err |
|
| 65 |
+ } |
|
| 59 | 66 |
} |
| 60 | 67 |
|
| 61 | 68 |
return nil |
| ... | ... |
@@ -73,7 +80,7 @@ func (d *driver) populateNetworks() error {
|
| 73 | 73 |
} |
| 74 | 74 |
for _, kvo := range kvol {
|
| 75 | 75 |
config := kvo.(*configuration) |
| 76 |
- if err = d.createNetwork(config); err != nil {
|
|
| 76 |
+ if _, err = d.createNetwork(config); err != nil {
|
|
| 77 | 77 |
logrus.Warnf("could not create ipvlan network for id %s from persistent state", config.ID)
|
| 78 | 78 |
} |
| 79 | 79 |
} |
| ... | ... |
@@ -64,10 +64,15 @@ func (d *driver) CreateNetwork(nid string, option map[string]interface{}, nInfo
|
| 64 | 64 |
// empty parent and --internal are handled the same. Set here to update k/v |
| 65 | 65 |
config.Internal = true |
| 66 | 66 |
} |
| 67 |
- err = d.createNetwork(config) |
|
| 67 |
+ foundExisting, err := d.createNetwork(config) |
|
| 68 | 68 |
if err != nil {
|
| 69 | 69 |
return err |
| 70 | 70 |
} |
| 71 |
+ |
|
| 72 |
+ if foundExisting {
|
|
| 73 |
+ return types.InternalMaskableErrorf("restoring existing network %s", config.ID)
|
|
| 74 |
+ } |
|
| 75 |
+ |
|
| 71 | 76 |
// update persistent db, rollback on fail |
| 72 | 77 |
err = d.storeUpdate(config) |
| 73 | 78 |
if err != nil {
|
| ... | ... |
@@ -80,12 +85,18 @@ func (d *driver) CreateNetwork(nid string, option map[string]interface{}, nInfo
|
| 80 | 80 |
} |
| 81 | 81 |
|
| 82 | 82 |
// createNetwork is used by new network callbacks and persistent network cache |
| 83 |
-func (d *driver) createNetwork(config *configuration) error {
|
|
| 83 |
+func (d *driver) createNetwork(config *configuration) (bool, error) {
|
|
| 84 |
+ foundExisting := false |
|
| 84 | 85 |
networkList := d.getNetworks() |
| 85 | 86 |
for _, nw := range networkList {
|
| 86 | 87 |
if config.Parent == nw.config.Parent {
|
| 87 |
- return fmt.Errorf("network %s is already using parent interface %s",
|
|
| 88 |
- getDummyName(stringid.TruncateID(nw.config.ID)), config.Parent) |
|
| 88 |
+ if config.ID != nw.config.ID {
|
|
| 89 |
+ return false, fmt.Errorf("network %s is already using parent interface %s",
|
|
| 90 |
+ getDummyName(stringid.TruncateID(nw.config.ID)), config.Parent) |
|
| 91 |
+ } |
|
| 92 |
+ logrus.Debugf("Create Network for the same ID %s\n", config.ID)
|
|
| 93 |
+ foundExisting = true |
|
| 94 |
+ break |
|
| 89 | 95 |
} |
| 90 | 96 |
} |
| 91 | 97 |
if !parentExists(config.Parent) {
|
| ... | ... |
@@ -93,7 +104,7 @@ func (d *driver) createNetwork(config *configuration) error {
|
| 93 | 93 |
if config.Internal {
|
| 94 | 94 |
err := createDummyLink(config.Parent, getDummyName(stringid.TruncateID(config.ID))) |
| 95 | 95 |
if err != nil {
|
| 96 |
- return err |
|
| 96 |
+ return false, err |
|
| 97 | 97 |
} |
| 98 | 98 |
config.CreatedSlaveLink = true |
| 99 | 99 |
// notify the user in logs they have limited communications |
| ... | ... |
@@ -106,22 +117,24 @@ func (d *driver) createNetwork(config *configuration) error {
|
| 106 | 106 |
// a valid example is 'eth0.10' for a parent iface 'eth0' with a vlan id '10' |
| 107 | 107 |
err := createVlanLink(config.Parent) |
| 108 | 108 |
if err != nil {
|
| 109 |
- return err |
|
| 109 |
+ return false, err |
|
| 110 | 110 |
} |
| 111 | 111 |
// if driver created the networks slave link, record it for future deletion |
| 112 | 112 |
config.CreatedSlaveLink = true |
| 113 | 113 |
} |
| 114 | 114 |
} |
| 115 |
- n := &network{
|
|
| 116 |
- id: config.ID, |
|
| 117 |
- driver: d, |
|
| 118 |
- endpoints: endpointTable{},
|
|
| 119 |
- config: config, |
|
| 115 |
+ if !foundExisting {
|
|
| 116 |
+ n := &network{
|
|
| 117 |
+ id: config.ID, |
|
| 118 |
+ driver: d, |
|
| 119 |
+ endpoints: endpointTable{},
|
|
| 120 |
+ config: config, |
|
| 121 |
+ } |
|
| 122 |
+ // add the network |
|
| 123 |
+ d.addNetwork(n) |
|
| 120 | 124 |
} |
| 121 |
- // add the *network |
|
| 122 |
- d.addNetwork(n) |
|
| 123 | 125 |
|
| 124 |
- return nil |
|
| 126 |
+ return foundExisting, nil |
|
| 125 | 127 |
} |
| 126 | 128 |
|
| 127 | 129 |
// DeleteNetwork deletes the network for the specified driver type |
| ... | ... |
@@ -186,10 +199,12 @@ func parseNetworkOptions(id string, option options.Generic) (*configuration, err |
| 186 | 186 |
} |
| 187 | 187 |
} |
| 188 | 188 |
// setting the parent to "" will trigger an isolated network dummy parent link |
| 189 |
- if _, ok := option[netlabel.Internal]; ok {
|
|
| 190 |
- config.Internal = true |
|
| 191 |
- // empty --parent= and --internal are handled the same. |
|
| 192 |
- config.Parent = "" |
|
| 189 |
+ if val, ok := option[netlabel.Internal]; ok {
|
|
| 190 |
+ if internal, ok := val.(bool); ok && internal {
|
|
| 191 |
+ config.Internal = true |
|
| 192 |
+ // empty --parent= and --internal are handled the same. |
|
| 193 |
+ config.Parent = "" |
|
| 194 |
+ } |
|
| 193 | 195 |
} |
| 194 | 196 |
|
| 195 | 197 |
return config, nil |
| ... | ... |
@@ -55,7 +55,15 @@ func (d *driver) initStore(option map[string]interface{}) error {
|
| 55 | 55 |
return types.InternalErrorf("macvlan driver failed to initialize data store: %v", err)
|
| 56 | 56 |
} |
| 57 | 57 |
|
| 58 |
- return d.populateNetworks() |
|
| 58 |
+ err = d.populateNetworks() |
|
| 59 |
+ if err != nil {
|
|
| 60 |
+ return err |
|
| 61 |
+ } |
|
| 62 |
+ err = d.populateEndpoints() |
|
| 63 |
+ if err != nil {
|
|
| 64 |
+ return err |
|
| 65 |
+ } |
|
| 66 |
+ |
|
| 59 | 67 |
} |
| 60 | 68 |
|
| 61 | 69 |
return nil |
| ... | ... |
@@ -73,7 +81,7 @@ func (d *driver) populateNetworks() error {
|
| 73 | 73 |
} |
| 74 | 74 |
for _, kvo := range kvol {
|
| 75 | 75 |
config := kvo.(*configuration) |
| 76 |
- if err = d.createNetwork(config); err != nil {
|
|
| 76 |
+ if _, err = d.createNetwork(config); err != nil {
|
|
| 77 | 77 |
logrus.Warnf("Could not create macvlan network for id %s from persistent state", config.ID)
|
| 78 | 78 |
} |
| 79 | 79 |
} |
| ... | ... |
@@ -72,11 +72,13 @@ func (e ChainError) Error() string {
|
| 72 | 72 |
} |
| 73 | 73 |
|
| 74 | 74 |
func probe() {
|
| 75 |
- if out, err := exec.Command("modprobe", "-va", "nf_nat").CombinedOutput(); err != nil {
|
|
| 76 |
- logrus.Warnf("Running modprobe nf_nat failed with message: `%s`, error: %v", strings.TrimSpace(string(out)), err)
|
|
| 75 |
+ path, err := exec.LookPath("iptables")
|
|
| 76 |
+ if err != nil {
|
|
| 77 |
+ logrus.Warnf("Failed to find iptables: %v", err)
|
|
| 78 |
+ return |
|
| 77 | 79 |
} |
| 78 |
- if out, err := exec.Command("modprobe", "-va", "xt_conntrack").CombinedOutput(); err != nil {
|
|
| 79 |
- logrus.Warnf("Running modprobe xt_conntrack failed with message: `%s`, error: %v", strings.TrimSpace(string(out)), err)
|
|
| 80 |
+ if out, err := exec.Command(path, "--wait", "-t", "nat", "-L", "-n").CombinedOutput(); err != nil {
|
|
| 81 |
+ logrus.Warnf("Running iptables --wait -t nat -L -n failed with message: `%s`, error: %v", strings.TrimSpace(string(out)), err)
|
|
| 80 | 82 |
} |
| 81 | 83 |
} |
| 82 | 84 |
|
| ... | ... |
@@ -422,8 +422,11 @@ func assembleDestination(attrs []syscall.NetlinkRouteAttr) (*Destination, error) |
| 422 | 422 |
attrType := int(attr.Attr.Type) |
| 423 | 423 |
|
| 424 | 424 |
switch attrType {
|
| 425 |
+ |
|
| 426 |
+ case ipvsDestAttrAddressFamily: |
|
| 427 |
+ d.AddressFamily = native.Uint16(attr.Value) |
|
| 425 | 428 |
case ipvsDestAttrAddress: |
| 426 |
- ip, err := parseIP(attr.Value, syscall.AF_INET) |
|
| 429 |
+ ip, err := parseIP(attr.Value, d.AddressFamily) |
|
| 427 | 430 |
if err != nil {
|
| 428 | 431 |
return nil, err |
| 429 | 432 |
} |
| ... | ... |
@@ -438,8 +441,6 @@ func assembleDestination(attrs []syscall.NetlinkRouteAttr) (*Destination, error) |
| 438 | 438 |
d.UpperThreshold = native.Uint32(attr.Value) |
| 439 | 439 |
case ipvsDestAttrLowerThreshold: |
| 440 | 440 |
d.LowerThreshold = native.Uint32(attr.Value) |
| 441 |
- case ipvsDestAttrAddressFamily: |
|
| 442 |
- d.AddressFamily = native.Uint16(attr.Value) |
|
| 443 | 441 |
case ipvsDestAttrActiveConnections: |
| 444 | 442 |
d.ActiveConnections = int(native.Uint16(attr.Value)) |
| 445 | 443 |
case ipvsDestAttrInactiveConnections: |
| ... | ... |
@@ -76,12 +76,8 @@ func NlHandle() *netlink.Handle {
|
| 76 | 76 |
func getSupportedNlFamilies() []int {
|
| 77 | 77 |
fams := []int{syscall.NETLINK_ROUTE}
|
| 78 | 78 |
// NETLINK_XFRM test |
| 79 |
- if err := loadXfrmModules(); err != nil {
|
|
| 80 |
- if checkXfrmSocket() != nil {
|
|
| 81 |
- logrus.Warnf("Could not load necessary modules for IPSEC rules: %v", err)
|
|
| 82 |
- } else {
|
|
| 83 |
- fams = append(fams, syscall.NETLINK_XFRM) |
|
| 84 |
- } |
|
| 79 |
+ if err := checkXfrmSocket(); err != nil {
|
|
| 80 |
+ logrus.Warnf("Could not load necessary modules for IPSEC rules: %v", err)
|
|
| 85 | 81 |
} else {
|
| 86 | 82 |
fams = append(fams, syscall.NETLINK_XFRM) |
| 87 | 83 |
} |
| ... | ... |
@@ -99,16 +95,6 @@ func getSupportedNlFamilies() []int {
|
| 99 | 99 |
return fams |
| 100 | 100 |
} |
| 101 | 101 |
|
| 102 |
-func loadXfrmModules() error {
|
|
| 103 |
- if out, err := exec.Command("modprobe", "-va", "xfrm_user").CombinedOutput(); err != nil {
|
|
| 104 |
- return fmt.Errorf("Running modprobe xfrm_user failed with message: `%s`, error: %v", strings.TrimSpace(string(out)), err)
|
|
| 105 |
- } |
|
| 106 |
- if out, err := exec.Command("modprobe", "-va", "xfrm_algo").CombinedOutput(); err != nil {
|
|
| 107 |
- return fmt.Errorf("Running modprobe xfrm_algo failed with message: `%s`, error: %v", strings.TrimSpace(string(out)), err)
|
|
| 108 |
- } |
|
| 109 |
- return nil |
|
| 110 |
-} |
|
| 111 |
- |
|
| 112 | 102 |
// API check on required xfrm modules (xfrm_user, xfrm_algo) |
| 113 | 103 |
func checkXfrmSocket() error {
|
| 114 | 104 |
fd, err := syscall.Socket(syscall.AF_NETLINK, syscall.SOCK_RAW, syscall.NETLINK_XFRM) |