xfrm_policy_linux.go 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. package netlink
  2. import (
  3. "github.com/vishvananda/netlink/nl"
  4. "golang.org/x/sys/unix"
  5. )
  6. func selFromPolicy(sel *nl.XfrmSelector, policy *XfrmPolicy) {
  7. sel.Family = uint16(nl.FAMILY_V4)
  8. if policy.Dst != nil {
  9. sel.Family = uint16(nl.GetIPFamily(policy.Dst.IP))
  10. sel.Daddr.FromIP(policy.Dst.IP)
  11. prefixlenD, _ := policy.Dst.Mask.Size()
  12. sel.PrefixlenD = uint8(prefixlenD)
  13. }
  14. if policy.Src != nil {
  15. sel.Saddr.FromIP(policy.Src.IP)
  16. prefixlenS, _ := policy.Src.Mask.Size()
  17. sel.PrefixlenS = uint8(prefixlenS)
  18. }
  19. sel.Proto = uint8(policy.Proto)
  20. sel.Dport = nl.Swap16(uint16(policy.DstPort))
  21. sel.Sport = nl.Swap16(uint16(policy.SrcPort))
  22. if sel.Dport != 0 {
  23. sel.DportMask = ^uint16(0)
  24. }
  25. if sel.Sport != 0 {
  26. sel.SportMask = ^uint16(0)
  27. }
  28. sel.Ifindex = int32(policy.Ifindex)
  29. }
  30. // XfrmPolicyAdd will add an xfrm policy to the system.
  31. // Equivalent to: `ip xfrm policy add $policy`
  32. func XfrmPolicyAdd(policy *XfrmPolicy) error {
  33. return pkgHandle.XfrmPolicyAdd(policy)
  34. }
  35. // XfrmPolicyAdd will add an xfrm policy to the system.
  36. // Equivalent to: `ip xfrm policy add $policy`
  37. func (h *Handle) XfrmPolicyAdd(policy *XfrmPolicy) error {
  38. return h.xfrmPolicyAddOrUpdate(policy, nl.XFRM_MSG_NEWPOLICY)
  39. }
  40. // XfrmPolicyUpdate will update an xfrm policy to the system.
  41. // Equivalent to: `ip xfrm policy update $policy`
  42. func XfrmPolicyUpdate(policy *XfrmPolicy) error {
  43. return pkgHandle.XfrmPolicyUpdate(policy)
  44. }
  45. // XfrmPolicyUpdate will update an xfrm policy to the system.
  46. // Equivalent to: `ip xfrm policy update $policy`
  47. func (h *Handle) XfrmPolicyUpdate(policy *XfrmPolicy) error {
  48. return h.xfrmPolicyAddOrUpdate(policy, nl.XFRM_MSG_UPDPOLICY)
  49. }
  50. func (h *Handle) xfrmPolicyAddOrUpdate(policy *XfrmPolicy, nlProto int) error {
  51. req := h.newNetlinkRequest(nlProto, unix.NLM_F_CREATE|unix.NLM_F_EXCL|unix.NLM_F_ACK)
  52. msg := &nl.XfrmUserpolicyInfo{}
  53. selFromPolicy(&msg.Sel, policy)
  54. msg.Priority = uint32(policy.Priority)
  55. msg.Index = uint32(policy.Index)
  56. msg.Dir = uint8(policy.Dir)
  57. msg.Action = uint8(policy.Action)
  58. msg.Lft.SoftByteLimit = nl.XFRM_INF
  59. msg.Lft.HardByteLimit = nl.XFRM_INF
  60. msg.Lft.SoftPacketLimit = nl.XFRM_INF
  61. msg.Lft.HardPacketLimit = nl.XFRM_INF
  62. req.AddData(msg)
  63. tmplData := make([]byte, nl.SizeofXfrmUserTmpl*len(policy.Tmpls))
  64. for i, tmpl := range policy.Tmpls {
  65. start := i * nl.SizeofXfrmUserTmpl
  66. userTmpl := nl.DeserializeXfrmUserTmpl(tmplData[start : start+nl.SizeofXfrmUserTmpl])
  67. userTmpl.XfrmId.Daddr.FromIP(tmpl.Dst)
  68. userTmpl.Saddr.FromIP(tmpl.Src)
  69. userTmpl.XfrmId.Proto = uint8(tmpl.Proto)
  70. userTmpl.XfrmId.Spi = nl.Swap32(uint32(tmpl.Spi))
  71. userTmpl.Mode = uint8(tmpl.Mode)
  72. userTmpl.Reqid = uint32(tmpl.Reqid)
  73. userTmpl.Optional = uint8(tmpl.Optional)
  74. userTmpl.Aalgos = ^uint32(0)
  75. userTmpl.Ealgos = ^uint32(0)
  76. userTmpl.Calgos = ^uint32(0)
  77. }
  78. if len(tmplData) > 0 {
  79. tmpls := nl.NewRtAttr(nl.XFRMA_TMPL, tmplData)
  80. req.AddData(tmpls)
  81. }
  82. if policy.Mark != nil {
  83. out := nl.NewRtAttr(nl.XFRMA_MARK, writeMark(policy.Mark))
  84. req.AddData(out)
  85. }
  86. if policy.Ifid != 0 {
  87. ifId := nl.NewRtAttr(nl.XFRMA_IF_ID, nl.Uint32Attr(uint32(policy.Ifid)))
  88. req.AddData(ifId)
  89. }
  90. _, err := req.Execute(unix.NETLINK_XFRM, 0)
  91. return err
  92. }
  93. // XfrmPolicyDel will delete an xfrm policy from the system. Note that
  94. // the Tmpls are ignored when matching the policy to delete.
  95. // Equivalent to: `ip xfrm policy del $policy`
  96. func XfrmPolicyDel(policy *XfrmPolicy) error {
  97. return pkgHandle.XfrmPolicyDel(policy)
  98. }
  99. // XfrmPolicyDel will delete an xfrm policy from the system. Note that
  100. // the Tmpls are ignored when matching the policy to delete.
  101. // Equivalent to: `ip xfrm policy del $policy`
  102. func (h *Handle) XfrmPolicyDel(policy *XfrmPolicy) error {
  103. _, err := h.xfrmPolicyGetOrDelete(policy, nl.XFRM_MSG_DELPOLICY)
  104. return err
  105. }
  106. // XfrmPolicyList gets a list of xfrm policies in the system.
  107. // Equivalent to: `ip xfrm policy show`.
  108. // The list can be filtered by ip family.
  109. func XfrmPolicyList(family int) ([]XfrmPolicy, error) {
  110. return pkgHandle.XfrmPolicyList(family)
  111. }
  112. // XfrmPolicyList gets a list of xfrm policies in the system.
  113. // Equivalent to: `ip xfrm policy show`.
  114. // The list can be filtered by ip family.
  115. func (h *Handle) XfrmPolicyList(family int) ([]XfrmPolicy, error) {
  116. req := h.newNetlinkRequest(nl.XFRM_MSG_GETPOLICY, unix.NLM_F_DUMP)
  117. msg := nl.NewIfInfomsg(family)
  118. req.AddData(msg)
  119. msgs, err := req.Execute(unix.NETLINK_XFRM, nl.XFRM_MSG_NEWPOLICY)
  120. if err != nil {
  121. return nil, err
  122. }
  123. var res []XfrmPolicy
  124. for _, m := range msgs {
  125. if policy, err := parseXfrmPolicy(m, family); err == nil {
  126. res = append(res, *policy)
  127. } else if err == familyError {
  128. continue
  129. } else {
  130. return nil, err
  131. }
  132. }
  133. return res, nil
  134. }
  135. // XfrmPolicyGet gets a the policy described by the index or selector, if found.
  136. // Equivalent to: `ip xfrm policy get { SELECTOR | index INDEX } dir DIR [ctx CTX ] [ mark MARK [ mask MASK ] ] [ ptype PTYPE ]`.
  137. func XfrmPolicyGet(policy *XfrmPolicy) (*XfrmPolicy, error) {
  138. return pkgHandle.XfrmPolicyGet(policy)
  139. }
  140. // XfrmPolicyGet gets a the policy described by the index or selector, if found.
  141. // Equivalent to: `ip xfrm policy get { SELECTOR | index INDEX } dir DIR [ctx CTX ] [ mark MARK [ mask MASK ] ] [ ptype PTYPE ]`.
  142. func (h *Handle) XfrmPolicyGet(policy *XfrmPolicy) (*XfrmPolicy, error) {
  143. return h.xfrmPolicyGetOrDelete(policy, nl.XFRM_MSG_GETPOLICY)
  144. }
  145. // XfrmPolicyFlush will flush the policies on the system.
  146. // Equivalent to: `ip xfrm policy flush`
  147. func XfrmPolicyFlush() error {
  148. return pkgHandle.XfrmPolicyFlush()
  149. }
  150. // XfrmPolicyFlush will flush the policies on the system.
  151. // Equivalent to: `ip xfrm policy flush`
  152. func (h *Handle) XfrmPolicyFlush() error {
  153. req := h.newNetlinkRequest(nl.XFRM_MSG_FLUSHPOLICY, unix.NLM_F_ACK)
  154. _, err := req.Execute(unix.NETLINK_XFRM, 0)
  155. return err
  156. }
  157. func (h *Handle) xfrmPolicyGetOrDelete(policy *XfrmPolicy, nlProto int) (*XfrmPolicy, error) {
  158. req := h.newNetlinkRequest(nlProto, unix.NLM_F_ACK)
  159. msg := &nl.XfrmUserpolicyId{}
  160. selFromPolicy(&msg.Sel, policy)
  161. msg.Index = uint32(policy.Index)
  162. msg.Dir = uint8(policy.Dir)
  163. req.AddData(msg)
  164. if policy.Mark != nil {
  165. out := nl.NewRtAttr(nl.XFRMA_MARK, writeMark(policy.Mark))
  166. req.AddData(out)
  167. }
  168. if policy.Ifid != 0 {
  169. ifId := nl.NewRtAttr(nl.XFRMA_IF_ID, nl.Uint32Attr(uint32(policy.Ifid)))
  170. req.AddData(ifId)
  171. }
  172. resType := nl.XFRM_MSG_NEWPOLICY
  173. if nlProto == nl.XFRM_MSG_DELPOLICY {
  174. resType = 0
  175. }
  176. msgs, err := req.Execute(unix.NETLINK_XFRM, uint16(resType))
  177. if err != nil {
  178. return nil, err
  179. }
  180. if nlProto == nl.XFRM_MSG_DELPOLICY {
  181. return nil, err
  182. }
  183. return parseXfrmPolicy(msgs[0], FAMILY_ALL)
  184. }
  185. func parseXfrmPolicy(m []byte, family int) (*XfrmPolicy, error) {
  186. msg := nl.DeserializeXfrmUserpolicyInfo(m)
  187. // This is mainly for the policy dump
  188. if family != FAMILY_ALL && family != int(msg.Sel.Family) {
  189. return nil, familyError
  190. }
  191. var policy XfrmPolicy
  192. policy.Dst = msg.Sel.Daddr.ToIPNet(msg.Sel.PrefixlenD)
  193. policy.Src = msg.Sel.Saddr.ToIPNet(msg.Sel.PrefixlenS)
  194. policy.Proto = Proto(msg.Sel.Proto)
  195. policy.DstPort = int(nl.Swap16(msg.Sel.Dport))
  196. policy.SrcPort = int(nl.Swap16(msg.Sel.Sport))
  197. policy.Ifindex = int(msg.Sel.Ifindex)
  198. policy.Priority = int(msg.Priority)
  199. policy.Index = int(msg.Index)
  200. policy.Dir = Dir(msg.Dir)
  201. policy.Action = PolicyAction(msg.Action)
  202. attrs, err := nl.ParseRouteAttr(m[msg.Len():])
  203. if err != nil {
  204. return nil, err
  205. }
  206. for _, attr := range attrs {
  207. switch attr.Attr.Type {
  208. case nl.XFRMA_TMPL:
  209. max := len(attr.Value)
  210. for i := 0; i < max; i += nl.SizeofXfrmUserTmpl {
  211. var resTmpl XfrmPolicyTmpl
  212. tmpl := nl.DeserializeXfrmUserTmpl(attr.Value[i : i+nl.SizeofXfrmUserTmpl])
  213. resTmpl.Dst = tmpl.XfrmId.Daddr.ToIP()
  214. resTmpl.Src = tmpl.Saddr.ToIP()
  215. resTmpl.Proto = Proto(tmpl.XfrmId.Proto)
  216. resTmpl.Mode = Mode(tmpl.Mode)
  217. resTmpl.Spi = int(nl.Swap32(tmpl.XfrmId.Spi))
  218. resTmpl.Reqid = int(tmpl.Reqid)
  219. resTmpl.Optional = int(tmpl.Optional)
  220. policy.Tmpls = append(policy.Tmpls, resTmpl)
  221. }
  222. case nl.XFRMA_MARK:
  223. mark := nl.DeserializeXfrmMark(attr.Value[:])
  224. policy.Mark = new(XfrmMark)
  225. policy.Mark.Value = mark.Value
  226. policy.Mark.Mask = mark.Mask
  227. case nl.XFRMA_IF_ID:
  228. policy.Ifid = int(native.Uint32(attr.Value))
  229. }
  230. }
  231. return &policy, nil
  232. }