multipath.c 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. /* multipath.c: IPV4 multipath algorithm support.
  2. *
  3. * Copyright (C) 2004, 2005 Einar Lueck <elueck@de.ibm.com>
  4. * Copyright (C) 2005 David S. Miller <davem@davemloft.net>
  5. */
  6. #include <linux/module.h>
  7. #include <linux/errno.h>
  8. #include <linux/netdevice.h>
  9. #include <linux/spinlock.h>
  10. #include <net/ip_mp_alg.h>
  11. static DEFINE_SPINLOCK(alg_table_lock);
  12. struct ip_mp_alg_ops *ip_mp_alg_table[IP_MP_ALG_MAX + 1];
  13. int multipath_alg_register(struct ip_mp_alg_ops *ops, enum ip_mp_alg n)
  14. {
  15. struct ip_mp_alg_ops **slot;
  16. int err;
  17. if (n < IP_MP_ALG_NONE || n > IP_MP_ALG_MAX ||
  18. !ops->mp_alg_select_route)
  19. return -EINVAL;
  20. spin_lock(&alg_table_lock);
  21. slot = &ip_mp_alg_table[n];
  22. if (*slot != NULL) {
  23. err = -EBUSY;
  24. } else {
  25. *slot = ops;
  26. err = 0;
  27. }
  28. spin_unlock(&alg_table_lock);
  29. return err;
  30. }
  31. EXPORT_SYMBOL(multipath_alg_register);
  32. void multipath_alg_unregister(struct ip_mp_alg_ops *ops, enum ip_mp_alg n)
  33. {
  34. struct ip_mp_alg_ops **slot;
  35. if (n < IP_MP_ALG_NONE || n > IP_MP_ALG_MAX)
  36. return;
  37. spin_lock(&alg_table_lock);
  38. slot = &ip_mp_alg_table[n];
  39. if (*slot == ops)
  40. *slot = NULL;
  41. spin_unlock(&alg_table_lock);
  42. synchronize_net();
  43. }
  44. EXPORT_SYMBOL(multipath_alg_unregister);