Tizen_4.0 base
[platform/upstream/docker-engine.git] / vendor / github.com / vishvananda / netlink / genetlink_linux.go
1 package netlink
2
3 import (
4         "fmt"
5         "syscall"
6
7         "github.com/vishvananda/netlink/nl"
8 )
9
10 type GenlOp struct {
11         ID    uint32
12         Flags uint32
13 }
14
15 type GenlMulticastGroup struct {
16         ID   uint32
17         Name string
18 }
19
20 type GenlFamily struct {
21         ID      uint16
22         HdrSize uint32
23         Name    string
24         Version uint32
25         MaxAttr uint32
26         Ops     []GenlOp
27         Groups  []GenlMulticastGroup
28 }
29
30 func parseOps(b []byte) ([]GenlOp, error) {
31         attrs, err := nl.ParseRouteAttr(b)
32         if err != nil {
33                 return nil, err
34         }
35         ops := make([]GenlOp, 0, len(attrs))
36         for _, a := range attrs {
37                 nattrs, err := nl.ParseRouteAttr(a.Value)
38                 if err != nil {
39                         return nil, err
40                 }
41                 var op GenlOp
42                 for _, na := range nattrs {
43                         switch na.Attr.Type {
44                         case nl.GENL_CTRL_ATTR_OP_ID:
45                                 op.ID = native.Uint32(na.Value)
46                         case nl.GENL_CTRL_ATTR_OP_FLAGS:
47                                 op.Flags = native.Uint32(na.Value)
48                         }
49                 }
50                 ops = append(ops, op)
51         }
52         return ops, nil
53 }
54
55 func parseMulticastGroups(b []byte) ([]GenlMulticastGroup, error) {
56         attrs, err := nl.ParseRouteAttr(b)
57         if err != nil {
58                 return nil, err
59         }
60         groups := make([]GenlMulticastGroup, 0, len(attrs))
61         for _, a := range attrs {
62                 nattrs, err := nl.ParseRouteAttr(a.Value)
63                 if err != nil {
64                         return nil, err
65                 }
66                 var g GenlMulticastGroup
67                 for _, na := range nattrs {
68                         switch na.Attr.Type {
69                         case nl.GENL_CTRL_ATTR_MCAST_GRP_NAME:
70                                 g.Name = nl.BytesToString(na.Value)
71                         case nl.GENL_CTRL_ATTR_MCAST_GRP_ID:
72                                 g.ID = native.Uint32(na.Value)
73                         }
74                 }
75                 groups = append(groups, g)
76         }
77         return groups, nil
78 }
79
80 func (f *GenlFamily) parseAttributes(attrs []syscall.NetlinkRouteAttr) error {
81         for _, a := range attrs {
82                 switch a.Attr.Type {
83                 case nl.GENL_CTRL_ATTR_FAMILY_NAME:
84                         f.Name = nl.BytesToString(a.Value)
85                 case nl.GENL_CTRL_ATTR_FAMILY_ID:
86                         f.ID = native.Uint16(a.Value)
87                 case nl.GENL_CTRL_ATTR_VERSION:
88                         f.Version = native.Uint32(a.Value)
89                 case nl.GENL_CTRL_ATTR_HDRSIZE:
90                         f.HdrSize = native.Uint32(a.Value)
91                 case nl.GENL_CTRL_ATTR_MAXATTR:
92                         f.MaxAttr = native.Uint32(a.Value)
93                 case nl.GENL_CTRL_ATTR_OPS:
94                         ops, err := parseOps(a.Value)
95                         if err != nil {
96                                 return err
97                         }
98                         f.Ops = ops
99                 case nl.GENL_CTRL_ATTR_MCAST_GROUPS:
100                         groups, err := parseMulticastGroups(a.Value)
101                         if err != nil {
102                                 return err
103                         }
104                         f.Groups = groups
105                 }
106         }
107
108         return nil
109 }
110
111 func parseFamilies(msgs [][]byte) ([]*GenlFamily, error) {
112         families := make([]*GenlFamily, 0, len(msgs))
113         for _, m := range msgs {
114                 attrs, err := nl.ParseRouteAttr(m[nl.SizeofGenlmsg:])
115                 if err != nil {
116                         return nil, err
117                 }
118                 family := &GenlFamily{}
119                 if err := family.parseAttributes(attrs); err != nil {
120                         return nil, err
121                 }
122
123                 families = append(families, family)
124         }
125         return families, nil
126 }
127
128 func (h *Handle) GenlFamilyList() ([]*GenlFamily, error) {
129         msg := &nl.Genlmsg{
130                 Command: nl.GENL_CTRL_CMD_GETFAMILY,
131                 Version: nl.GENL_CTRL_VERSION,
132         }
133         req := h.newNetlinkRequest(nl.GENL_ID_CTRL, syscall.NLM_F_DUMP)
134         req.AddData(msg)
135         msgs, err := req.Execute(syscall.NETLINK_GENERIC, 0)
136         if err != nil {
137                 return nil, err
138         }
139         return parseFamilies(msgs)
140 }
141
142 func GenlFamilyList() ([]*GenlFamily, error) {
143         return pkgHandle.GenlFamilyList()
144 }
145
146 func (h *Handle) GenlFamilyGet(name string) (*GenlFamily, error) {
147         msg := &nl.Genlmsg{
148                 Command: nl.GENL_CTRL_CMD_GETFAMILY,
149                 Version: nl.GENL_CTRL_VERSION,
150         }
151         req := h.newNetlinkRequest(nl.GENL_ID_CTRL, 0)
152         req.AddData(msg)
153         req.AddData(nl.NewRtAttr(nl.GENL_CTRL_ATTR_FAMILY_NAME, nl.ZeroTerminated(name)))
154         msgs, err := req.Execute(syscall.NETLINK_GENERIC, 0)
155         if err != nil {
156                 return nil, err
157         }
158         families, err := parseFamilies(msgs)
159         if len(families) != 1 {
160                 return nil, fmt.Errorf("invalid response for GENL_CTRL_CMD_GETFAMILY")
161         }
162         return families[0], nil
163 }
164
165 func GenlFamilyGet(name string) (*GenlFamily, error) {
166         return pkgHandle.GenlFamilyGet(name)
167 }