mirror of
https://github.com/moby/moby.git
synced 2026-01-11 18:51:37 +00:00
Merge pull request #51223 from thaJeztah/cleaner_marshal
libnetwork: EndpointInterface: cleanup marshal/unmarshal
This commit is contained in:
@@ -54,94 +54,74 @@ type EndpointInterface struct {
|
|||||||
createdInContainer bool
|
createdInContainer bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// endpointInterface is an intermediate struct used to marshal/unmarshal
|
||||||
|
// am [EndpointInterface] to JSON.
|
||||||
|
//
|
||||||
|
// TODO(thaJeztah): use "omitzero" for all fields once we no longer have to consider downgrades to < v29.0; see https://github.com/moby/moby/pull/51223#discussion_r2445826610
|
||||||
|
type endpointInterface struct {
|
||||||
|
MAC string `json:"mac"`
|
||||||
|
Addr netip.Prefix `json:"addr"`
|
||||||
|
AddrV6 netip.Prefix `json:"addrv6"`
|
||||||
|
LLAddrs []netip.Prefix `json:"llAddrs"`
|
||||||
|
Routes []netip.Prefix `json:"routes"`
|
||||||
|
SrcName string `json:"srcName"`
|
||||||
|
DstPrefix string `json:"dstPrefix"`
|
||||||
|
DstName string `json:"dstName"`
|
||||||
|
V4PoolID string `json:"v4PoolID"`
|
||||||
|
V6PoolID string `json:"v6PoolID"`
|
||||||
|
CreatedInContainer bool `json:"createdInContainer"`
|
||||||
|
}
|
||||||
|
|
||||||
func (epi *EndpointInterface) MarshalJSON() ([]byte, error) {
|
func (epi *EndpointInterface) MarshalJSON() ([]byte, error) {
|
||||||
epMap := make(map[string]any)
|
mac := ""
|
||||||
if epi.mac != nil {
|
if epi.mac != nil {
|
||||||
epMap["mac"] = epi.mac.String()
|
mac = epi.mac.String()
|
||||||
}
|
}
|
||||||
if epi.addr != nil {
|
|
||||||
epMap["addr"] = epi.addr.String()
|
return json.Marshal(&endpointInterface{
|
||||||
}
|
MAC: mac,
|
||||||
if epi.addrv6 != nil {
|
Addr: toPrefix(epi.addr),
|
||||||
epMap["addrv6"] = epi.addrv6.String()
|
AddrV6: toPrefix(epi.addrv6),
|
||||||
}
|
LLAddrs: toPrefixes(epi.llAddrs),
|
||||||
if len(epi.llAddrs) != 0 {
|
Routes: toPrefixes(epi.routes),
|
||||||
list := make([]string, 0, len(epi.llAddrs))
|
SrcName: epi.srcName,
|
||||||
for _, ll := range epi.llAddrs {
|
DstPrefix: epi.dstPrefix,
|
||||||
list = append(list, ll.String())
|
DstName: epi.dstName,
|
||||||
}
|
V4PoolID: epi.v4PoolID,
|
||||||
epMap["llAddrs"] = list
|
V6PoolID: epi.v6PoolID,
|
||||||
}
|
CreatedInContainer: epi.createdInContainer,
|
||||||
epMap["srcName"] = epi.srcName
|
})
|
||||||
epMap["dstPrefix"] = epi.dstPrefix
|
|
||||||
epMap["dstName"] = epi.dstName
|
|
||||||
var routes []string
|
|
||||||
for _, route := range epi.routes {
|
|
||||||
routes = append(routes, route.String())
|
|
||||||
}
|
|
||||||
epMap["routes"] = routes
|
|
||||||
epMap["v4PoolID"] = epi.v4PoolID
|
|
||||||
epMap["v6PoolID"] = epi.v6PoolID
|
|
||||||
epMap["createdInContainer"] = epi.createdInContainer
|
|
||||||
return json.Marshal(epMap)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (epi *EndpointInterface) UnmarshalJSON(b []byte) error {
|
func (epi *EndpointInterface) UnmarshalJSON(b []byte) error {
|
||||||
var (
|
var epiTmp endpointInterface
|
||||||
err error
|
if err := json.Unmarshal(b, &epiTmp); err != nil {
|
||||||
epMap map[string]any
|
|
||||||
)
|
|
||||||
if err = json.Unmarshal(b, &epMap); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if v, ok := epMap["mac"]; ok {
|
|
||||||
if epi.mac, err = net.ParseMAC(v.(string)); err != nil {
|
|
||||||
return types.InternalErrorf("failed to decode endpoint interface mac address after json unmarshal: %s", v.(string))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if v, ok := epMap["addr"]; ok {
|
|
||||||
if epi.addr, err = types.ParseCIDR(v.(string)); err != nil {
|
|
||||||
return types.InternalErrorf("failed to decode endpoint interface ipv4 address after json unmarshal: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if v, ok := epMap["addrv6"]; ok {
|
|
||||||
if epi.addrv6, err = types.ParseCIDR(v.(string)); err != nil {
|
|
||||||
return types.InternalErrorf("failed to decode endpoint interface ipv6 address after json unmarshal: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if v, ok := epMap["llAddrs"]; ok {
|
|
||||||
list := v.([]any)
|
|
||||||
epi.llAddrs = make([]*net.IPNet, 0, len(list))
|
|
||||||
for _, llS := range list {
|
|
||||||
ll, err := types.ParseCIDR(llS.(string))
|
|
||||||
if err != nil {
|
|
||||||
return types.InternalErrorf("failed to decode endpoint interface link-local address (%v) after json unmarshal: %v", llS, err)
|
|
||||||
}
|
|
||||||
epi.llAddrs = append(epi.llAddrs, ll)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
epi.srcName = epMap["srcName"].(string)
|
|
||||||
epi.dstPrefix = epMap["dstPrefix"].(string)
|
|
||||||
|
|
||||||
// TODO(cpuguy83): linter noticed we don't check the error here... no idea why but it seems like it could introduce problems if we start checking
|
var mac net.HardwareAddr
|
||||||
rb, _ := json.Marshal(epMap["routes"]) //nolint:errchkjson // FIXME: handle json (Un)Marshal errors (see above)
|
if epiTmp.MAC != "" {
|
||||||
var routes []string
|
hw, err := net.ParseMAC(epiTmp.MAC)
|
||||||
_ = json.Unmarshal(rb, &routes) //nolint:errcheck
|
if err != nil {
|
||||||
|
return types.InternalErrorf("invalid mac %q: %v", epiTmp.MAC, err)
|
||||||
epi.routes = make([]*net.IPNet, 0)
|
|
||||||
for _, route := range routes {
|
|
||||||
ip, ipr, err := net.ParseCIDR(route)
|
|
||||||
if err == nil {
|
|
||||||
ipr.IP = ip
|
|
||||||
epi.routes = append(epi.routes, ipr)
|
|
||||||
}
|
}
|
||||||
|
mac = hw
|
||||||
}
|
}
|
||||||
epi.v4PoolID = epMap["v4PoolID"].(string)
|
|
||||||
epi.v6PoolID = epMap["v6PoolID"].(string)
|
|
||||||
|
|
||||||
if v, ok := epMap["createdInContainer"]; ok {
|
*epi = EndpointInterface{
|
||||||
epi.createdInContainer = v.(bool)
|
mac: mac,
|
||||||
|
addr: netiputil.ToIPNet(epiTmp.Addr),
|
||||||
|
addrv6: netiputil.ToIPNet(epiTmp.AddrV6),
|
||||||
|
llAddrs: toIPNets(epiTmp.LLAddrs),
|
||||||
|
routes: toIPNets(epiTmp.Routes),
|
||||||
|
srcName: epiTmp.SrcName,
|
||||||
|
dstPrefix: epiTmp.DstPrefix,
|
||||||
|
dstName: epiTmp.DstName,
|
||||||
|
v4PoolID: epiTmp.V4PoolID,
|
||||||
|
v6PoolID: epiTmp.V6PoolID,
|
||||||
|
createdInContainer: epiTmp.CreatedInContainer,
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -549,3 +529,28 @@ func (epj *endpointJoinInfo) Copy() *endpointJoinInfo {
|
|||||||
disableGatewayService: epj.disableGatewayService,
|
disableGatewayService: epj.disableGatewayService,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func toPrefix(n *net.IPNet) netip.Prefix {
|
||||||
|
p, _ := netiputil.ToPrefix(n)
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
|
func toIPNets(ps []netip.Prefix) []*net.IPNet {
|
||||||
|
out := make([]*net.IPNet, 0, len(ps))
|
||||||
|
for _, p := range ps {
|
||||||
|
if n := netiputil.ToIPNet(p); n != nil {
|
||||||
|
out = append(out, n)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
func toPrefixes(nets []*net.IPNet) []netip.Prefix {
|
||||||
|
out := make([]netip.Prefix, 0, len(nets))
|
||||||
|
for _, n := range nets {
|
||||||
|
if prefix, ok := netiputil.ToPrefix(n); ok {
|
||||||
|
out = append(out, prefix)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user