package org.freertr.tab; import java.util.ArrayList; import java.util.List; import org.freertr.cfg.cfgAll; import org.freertr.cfg.cfgIfc; import org.freertr.user.userFormat; import org.freertr.util.bits; import org.freertr.util.debugger; import org.freertr.util.logger; /** * represents one label table * * @author matecsaba */ public class tabLabel { /** * label table */ public final static tabGen labels = new tabGen(); private tabLabel() { } /** * get sh mpls for output * * @return list of string */ public static userFormat getShFor() { userFormat lst = new userFormat("|", "label|vrf|iface|hop|label|targets|bytes"); for (int i = 0; i < labels.size(); i++) { tabLabelEntry ntry = labels.get(i); if (ntry == null) { continue; } lst.add(ntry.getList()); } return lst; } /** * get sh mpls int output * * @return list of string */ public static userFormat getShInt() { userFormat lst = new userFormat("|", "interface|packet|mplsec|sr6sec|ldp4|ldp6|rsvp4|rsvp6"); for (int i = 0; i < cfgAll.ifaces.size(); i++) { cfgIfc ntry = cfgAll.ifaces.get(i); if (ntry == null) { continue; } boolean sec = false; if (ntry.mplsPack != null) { sec = ntry.mplsPack.security; } lst.add(ntry.name + "|" + (ntry.mplsPack != null) + "|" + sec + "|" + ntry.getSRv6sec() + "|" + (ntry.mplsLdp4 != null) + "|" + (ntry.mplsLdp6 != null) + "|" + (ntry.mplsRsvp4 != null) + "|" + (ntry.mplsRsvp6 != null)); } return lst; } /** * find one label * * @param label label to find * @return label entry, null if not found */ public static tabLabelEntry find(int label) { tabLabelEntry ntry = new tabLabelEntry(label); return labels.find(ntry); } /** * allocate exact label * * @param key key to use for deallocation * @param val value to allocate * @return label entry, null if nothing */ public static tabLabelEntry allocateExact(tabLabelEntry.owner key, int val) { if (debugger.tabLabelEvnt) { logger.debug("allocate " + val); } tabLabelEntry ntry = new tabLabelEntry(val); if (labels.add(ntry) != null) { logger.warn("failed to allocate exact label"); return null; } ntry.key = key; ntry.working = true; return ntry; } /** * allocate one label * * @param key key to use for deallocation * @return label entry, null if nothing */ public static tabLabelEntry allocate(tabLabelEntry.owner key) { for (int retry = 0; retry < 16; retry++) { int i = bits.random(cfgAll.labelRangeBeg, cfgAll.labelRangeEnd); tabLabelEntry ntry = new tabLabelEntry(i); if (labels.add(ntry) != null) { continue; } if (debugger.tabLabelEvnt) { logger.debug("allocate " + ntry.label); } ntry.key = key; ntry.working = true; return ntry; } logger.warn("failed to allocate new label"); return null; } private static tabLabelEntry[] allocBlock(tabLabelEntry.owner key, int beg, int num) { tabLabelEntry[] res = new tabLabelEntry[num]; for (int i = 0; i < num; i++) { tabLabelEntry ntry = new tabLabelEntry(beg + i); if (labels.add(ntry) != null) { release(res, key); return null; } if (debugger.tabLabelEvnt) { logger.debug("allocate " + ntry.label); } ntry.key = key; ntry.working = true; res[i] = ntry; } return res; } /** * allocate label block * * @param key key to use for deallocation * @param num number of labels * @return label list, null if nothing */ public static tabLabelEntry[] allocate(tabLabelEntry.owner key, int num) { if (num < 1) { return null; } for (int retry = 0; retry < 32; retry++) { int beg = bits.random(cfgAll.labelRangeBeg, cfgAll.labelRangeEnd - num); tabLabelEntry[] res = allocBlock(key, beg, num); if (res != null) { return res; } } logger.warn("failed to allocate new label block"); return null; } /** * allocate label block * * @param key key to use for deallocation * @param beg beginning of block * @param num number of labels * @return label list, null if nothing */ public static tabLabelEntry[] allocate(tabLabelEntry.owner key, int beg, int num) { if (num < 1) { return null; } if (beg < 1) { return allocate(key, num); } tabLabelEntry[] res = allocBlock(key, beg, num); if (res != null) { return res; } logger.warn("failed to allocate specific label block"); return allocate(key, num); } /** * delete one label * * @param label to delete * @param key key to use * @return label entry, null if nothing */ public static tabLabelEntry release(tabLabelEntry label, tabLabelEntry.owner key) { if (label == null) { return null; } if (!label.working) { return null; } if (label.key != key) { return null; } if (debugger.tabLabelEvnt) { logger.debug("release " + label.label); } label = labels.del(label); if (label == null) { return null; } label.working = false; return label; } /** * delete label block * * @param label to delete * @param key key to use * @return label entry, null if nothing */ public static tabLabelEntry[] release(tabLabelEntry[] label, tabLabelEntry.owner key) { if (label == null) { return null; } tabLabelEntry[] res = new tabLabelEntry[label.length]; for (int i = 0; i < label.length; i++) { tabLabelEntry ntry = label[i]; ntry = release(ntry, key); res[i] = ntry; } return res; } /** * convert integer to list * * @param val value to convert * @return converted */ public static List int2labels(int val) { List res = new ArrayList(); res.add(val); return res; } /** * prepend some labels * * @param trg where to prepend * @param src labels to prepend * @return updated target list */ public static List prependLabels(List trg, List src) { if (src == null) { return trg; } if (src == trg) { return trg; } if (trg == null) { trg = new ArrayList(); } for (int i = 0; i < src.size(); i++) { trg.add(i, src.get(i)); } return trg; } /** * prepend one label * * @param trg where to prepend * @param val label to prepend * @return updated target list */ public static List prependLabel(List trg, int val) { return prependLabels(trg, int2labels(val)); } /** * copy labels * * @param src labels to copy * @return copyed labels */ public static List copyLabels(List src) { if (src == null) { return null; } List res = new ArrayList(); res.addAll(src); return res; } }