docs: def get_link(cls, source, target, topology=None):
          """
          Find link between source and target, (or vice versa, order is irrelevant).
          :param source: ip or mac addresses
          :param target: ip or mac addresses
          :param topology: optional topology relation
          :returns: Link object
          :raises: LinkNotFound
          """
          a = source
          b = target
          # ensure parameters are coherent
          if not (valid_ipv4(a) and valid_ipv4(b)) and not (valid_ipv6(a) and valid_ipv6(b)) and not (valid_mac(a) and valid_mac(b)):
              raise ValueError('Expecting valid ipv4, ipv6 or mac address')
          # get interfaces
          a = cls._get_link_interface(a)
          b = cls._get_link_interface(b)
          # raise LinkDataNotFound if an interface is not found
          not_found = []
          if a is None:
              not_found.append(source)
          if b is None:
              not_found.append(target)
          if not_found:
              msg = 'the following interfaces could not be found: {0}'.format(', '.join(not_found))
              raise LinkDataNotFound(msg)
          # find link with interfaces
          # inverse order is also ok
          q = (Q(interface_a=a, interface_b=b) | Q(interface_a=b, interface_b=a))
          # add topology to lookup
          if topology:
              q = q & Q(topology=topology)
          link = Link.objects.filter(q).first()
          if link is None:
              raise LinkNotFound('Link matching query does not exist',
                                 interface_a=a,
                                 interface_b=b,
                                 topology=topology)
          return link